/ocr/translate/src/com/google/marvin/translate/Translate.java

http://eyes-free.googlecode.com/ · Java · 333 lines · 245 code · 50 blank · 38 comment · 37 complexity · 3fb65115d2ea27f945dae520373f3ff8 MD5 · raw file

  1. /*
  2. * Copyright (C) 2009 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.google.marvin.translate;
  17. import android.app.Activity;
  18. import android.content.Intent;
  19. import android.content.SharedPreferences;
  20. import android.content.SharedPreferences.Editor;
  21. import android.content.res.Resources;
  22. import android.os.Bundle;
  23. import android.os.Parcelable;
  24. import android.text.Editable;
  25. import android.util.Log;
  26. import android.view.View;
  27. import android.widget.AdapterView;
  28. import android.widget.ArrayAdapter;
  29. import android.widget.Button;
  30. import android.widget.EditText;
  31. import android.widget.Spinner;
  32. import android.widget.Toast;
  33. import android.widget.AdapterView.OnItemSelectedListener;
  34. import com.android.ocr.client.Config;
  35. import com.android.ocr.client.Intents;
  36. import com.android.ocr.client.Language;
  37. import com.android.ocr.client.Ocr;
  38. import com.android.ocr.client.Result;
  39. import java.util.Arrays;
  40. /**
  41. * Main activity for Translate application. This app uses the Capture and
  42. * Recognize intents, in addition to a new Translate intent, to provide
  43. * photograph-based translation.
  44. *
  45. * @author alanv@google.com (Alan Viverette)
  46. */
  47. public class Translate extends Activity implements Button.OnClickListener {
  48. private static final String TAG = "Translate";
  49. private static final int PICTURE_WIDTH = 1024;
  50. private static final int PICTURE_HEIGHT = 768;
  51. private static final int REQUEST_CAPTURE = 0;
  52. private static final int REQUEST_RECOGNIZE = 1;
  53. private static final int REQUEST_TRANSLATE = 2;
  54. private EditText mEditText;
  55. private Button mOpenCapture;
  56. private Button mOpenTranslate;
  57. protected static Spinner mSource;
  58. private Spinner mTarget;
  59. protected static Ocr mOcr;
  60. protected static byte[] mImage;
  61. /** Called when the activity is first created. */
  62. @Override
  63. public void onCreate(Bundle savedInstanceState) {
  64. super.onCreate(savedInstanceState);
  65. setContentView(R.layout.main);
  66. mEditText = (EditText) findViewById(R.id.editText);
  67. mSource = (Spinner) findViewById(R.id.source);
  68. mTarget = (Spinner) findViewById(R.id.target);
  69. mOpenCapture = (Button) findViewById(R.id.openCapture);
  70. mOpenCapture.setOnClickListener(this);
  71. mOpenTranslate = (Button) findViewById(R.id.openTranslate);
  72. mOpenTranslate.setOnClickListener(this);
  73. mSource.setEnabled(false);
  74. mTarget.setEnabled(false);
  75. mOpenCapture.setEnabled(false);
  76. mOpenTranslate.setEnabled(false);
  77. Ocr.InitCallback onInit = new Ocr.InitCallback() {
  78. @Override
  79. public void onInitialized(int status) {
  80. switch (status) {
  81. case Ocr.STATUS_SUCCESS: {
  82. loadLanguages();
  83. mSource.setEnabled(true);
  84. mTarget.setEnabled(true);
  85. mOpenCapture.setEnabled(true);
  86. mOpenTranslate.setEnabled(true);
  87. break;
  88. }
  89. case Ocr.STATUS_MISSING:
  90. case Ocr.STATUS_FAILURE: {
  91. finish();
  92. break;
  93. }
  94. }
  95. }
  96. };
  97. mOcr = new Ocr(this, onInit);
  98. }
  99. @Override
  100. public void onDestroy() {
  101. if (mOcr != null) {
  102. mOcr.release();
  103. }
  104. super.onDestroy();
  105. }
  106. /**
  107. * Loads available destination languages from application resources and
  108. * available source languages from OCR library.
  109. */
  110. private void loadLanguages() {
  111. Log.i(TAG, "Loading languages...");
  112. // Load destination languages...
  113. Resources resources = getResources();
  114. String[] iso_639_1 = resources.getStringArray(R.array.iso_639_1);
  115. String[] iso_639_2 = resources.getStringArray(R.array.iso_639_2);
  116. String[] english = resources.getStringArray(R.array.english);
  117. Language[] dstLangs = new Language[english.length];
  118. // Add mappings for all destination languages
  119. for (int i = 0; i < dstLangs.length; i++) {
  120. dstLangs[i] = new Language(english[i], iso_639_1[i], iso_639_2[i]);
  121. }
  122. // Sort alphabetically by English name
  123. Arrays.sort(dstLangs);
  124. // Load source languages from supported OCR languages...
  125. Language[] ocrLangs = mOcr.getLanguages();
  126. Language[] srcLangs = new Language[ocrLangs.length + 1];
  127. // Add "Automatic" as a source languages option
  128. System.arraycopy(ocrLangs, 0, srcLangs, 1, ocrLangs.length);
  129. srcLangs[0] = new Language("Automatic", "", "eng");
  130. // Load preferences and find IDs for default languages
  131. SharedPreferences prefs = getPreferences(MODE_PRIVATE);
  132. String srcPref = prefs.getString("source_pref", "");
  133. String dstPref = prefs.getString("target_pref", "en");
  134. int defSrc = -1;
  135. int defDst = -1;
  136. for (int i = 0; i < dstLangs.length; i++) {
  137. if (defDst < 0 && dstLangs[i].iso_639_1.equals(dstPref)) {
  138. defDst = i;
  139. break;
  140. }
  141. }
  142. for (int i = 0; i < srcLangs.length; i++) {
  143. if (defSrc < 0 && srcLangs[i].iso_639_1.equals(srcPref)) {
  144. defSrc = i;
  145. }
  146. }
  147. // Set up source language drop-down view
  148. OnItemSelectedListener srcListener = new OnItemSelectedListener() {
  149. @Override
  150. public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
  151. setLanguagePreference("source_pref", mSource);
  152. }
  153. @Override
  154. public void onNothingSelected(AdapterView<?> arg0) {
  155. }
  156. };
  157. ArrayAdapter<Language> src =
  158. new ArrayAdapter<Language>(this, android.R.layout.simple_spinner_item, srcLangs);
  159. src.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  160. mSource.setAdapter(src);
  161. mSource.setSelection(defSrc);
  162. mSource.setOnItemSelectedListener(srcListener);
  163. // Set up destination language drop-down view
  164. OnItemSelectedListener dstListener = new OnItemSelectedListener() {
  165. @Override
  166. public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
  167. setLanguagePreference("target_pref", mTarget);
  168. }
  169. @Override
  170. public void onNothingSelected(AdapterView<?> arg0) {
  171. }
  172. };
  173. ArrayAdapter<Language> dst =
  174. new ArrayAdapter<Language>(this, android.R.layout.simple_spinner_item, dstLangs);
  175. dst.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  176. mTarget.setAdapter(dst);
  177. mTarget.setSelection(defDst);
  178. mTarget.setOnItemSelectedListener(dstListener);
  179. Log.i(TAG, "Languages loaded.");
  180. }
  181. @Override
  182. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  183. switch (requestCode) {
  184. case REQUEST_CAPTURE: {
  185. handleCaptureCompleted(resultCode, data);
  186. break;
  187. }
  188. case REQUEST_RECOGNIZE: {
  189. handleRecognizeCompleted(resultCode, data);
  190. break;
  191. }
  192. case REQUEST_TRANSLATE: {
  193. handleTranslateCompleted(resultCode, data);
  194. break;
  195. }
  196. default: {
  197. Log.i(TAG, "Unknown activity request code: " + requestCode);
  198. }
  199. }
  200. }
  201. private void setLanguagePreference(String pref, Spinner spin) {
  202. Language source = (Language) spin.getSelectedItem();
  203. SharedPreferences prefs = getPreferences(MODE_PRIVATE);
  204. Editor edit = prefs.edit();
  205. edit.putString(pref, source.iso_639_1);
  206. edit.commit();
  207. }
  208. private void startCaptureActivity() {
  209. Intent intent = new Intent(Intents.Capture.ACTION);
  210. intent.putExtra(Intents.Capture.WIDTH, PICTURE_WIDTH);
  211. intent.putExtra(Intents.Capture.HEIGHT, PICTURE_HEIGHT);
  212. startActivityForResult(intent, REQUEST_CAPTURE);
  213. }
  214. private void handleCaptureCompleted(int resultCode, Intent data) {
  215. if (resultCode == RESULT_CANCELED) {
  216. Toast.makeText(this, R.string.capture_failed, 5).show();
  217. Log.e(TAG, "REQUEST_CAPTURE received RESULT_CANCELED");
  218. } else if (resultCode == RESULT_OK) {
  219. startRecognizeActivity(data);
  220. } else {
  221. Log.i(TAG, "CaptureActivity returned unknown result code: " + resultCode);
  222. }
  223. }
  224. private void startRecognizeActivity(Intent data) {
  225. Language source = (Language) mSource.getSelectedItem();
  226. // Pull data from CaptureActivity's intent and add options
  227. Parcelable parcel = data.getParcelableExtra(Intents.Capture.CONFIG);
  228. Config config = (Config) parcel;
  229. config.language = source.iso_639_2;
  230. config.options |= Config.OPT_NORMALIZE_BG;
  231. // Load data into intent for RecognizeActivity
  232. Intent intent = new Intent(Intents.Recognize.ACTION);
  233. intent.putExtra(Intents.Recognize.CONFIG, config);
  234. startActivityForResult(intent, REQUEST_RECOGNIZE);
  235. }
  236. private void handleRecognizeCompleted(int resultCode, Intent data) {
  237. if (resultCode == RESULT_CANCELED) {
  238. Toast.makeText(this, R.string.recognize_canceled, 3).show();
  239. Log.i(TAG, "REQUEST_RECOGNIZED received RESULT_CANCELED");
  240. } else if (resultCode == RESULT_OK) {
  241. Parcelable[] results = data.getParcelableArrayExtra(Intents.Recognize.RESULTS);
  242. String query = "";
  243. if (results != null) {
  244. for (Parcelable result : results) {
  245. query += ((Result) result).getString();
  246. }
  247. }
  248. mEditText.setText(query);
  249. } else {
  250. Log.i(TAG, "OcrActivity returned unknown result code: " + resultCode);
  251. }
  252. }
  253. private void startTranslateActivity() {
  254. Language source = (Language) mSource.getSelectedItem();
  255. Language target = (Language) mTarget.getSelectedItem();
  256. Editable text = mEditText.getText();
  257. // Load data into intent for TranslateActivity
  258. Intent intent = new Intent(this, TranslateActivity.class);
  259. intent.putExtra(TranslateActivity.EXTRA_SOURCE, source.iso_639_1);
  260. intent.putExtra(TranslateActivity.EXTRA_TARGET, target.iso_639_1);
  261. intent.putExtra(TranslateActivity.EXTRA_QUERY, text.toString());
  262. startActivityForResult(intent, REQUEST_TRANSLATE);
  263. }
  264. private void handleTranslateCompleted(int resultCode, Intent data) {
  265. if (resultCode == RESULT_CANCELED) {
  266. Toast.makeText(this, R.string.translate_failed, 5).show();
  267. Log.e(TAG, "REQUEST_TRANSLATE received RESULT_CANCELED");
  268. } else if (resultCode == RESULT_OK) {
  269. String result = data.getStringExtra(TranslateActivity.EXTRA_RESULTS);
  270. mEditText.setText(result);
  271. } else {
  272. Log.i(TAG, "TranslateActivity returned unknown result code: " + resultCode);
  273. }
  274. }
  275. @Override
  276. public void onClick(View v) {
  277. if (v == mOpenCapture) {
  278. startCaptureActivity();
  279. } else if (v == mOpenTranslate) {
  280. startTranslateActivity();
  281. }
  282. }
  283. }