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