/ocr/ocrservice/src/com/googlecode/eyesfree/ocr/intent/LanguagesActivity.java
Java | 362 lines | 261 code | 77 blank | 24 comment | 26 complexity | 0282eaf9ffe7df3271cd69b335e5d05b MD5 | raw file
1/* 2 * Copyright (C) 2011 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 17package com.googlecode.eyesfree.ocr.intent; 18 19import android.app.Activity; 20import android.app.AlertDialog; 21import android.app.Dialog; 22import android.content.BroadcastReceiver; 23import android.content.Context; 24import android.content.DialogInterface; 25import android.content.Intent; 26import android.content.IntentFilter; 27import android.content.SharedPreferences; 28import android.content.res.Configuration; 29import android.os.Bundle; 30import android.util.Log; 31import android.view.LayoutInflater; 32import android.view.View; 33import android.view.ViewGroup; 34import android.widget.AdapterView; 35import android.widget.AdapterView.OnItemClickListener; 36import android.widget.ArrayAdapter; 37import android.widget.ListView; 38import android.widget.TextView; 39import android.widget.Toast; 40 41import com.googlecode.eyesfree.ocr.R; 42import com.googlecode.eyesfree.ocr.client.Intents; 43import com.googlecode.eyesfree.ocr.client.Language; 44import com.googlecode.eyesfree.ocr.client.Ocr; 45 46import java.io.File; 47import java.util.Collection; 48import java.util.List; 49import java.util.TreeSet; 50 51/** 52 * Displays available and installed languages, allows downloading of new 53 * language packs. 54 * 55 * @author alanv@google.com (Alan Viverette) 56 */ 57public class LanguagesActivity extends Activity { 58 private static final String TAG = "LanguagesActivity"; 59 60 private static final String XML_SOURCE = 61 "http://eyes-free.googlecode.com/svn/trunk/thirdparty/tesseract/languages.xml"; 62 63 private static final String DATA_SOURCE = 64 "http://eyes-free.googlecode.com/svn/trunk/thirdparty/tesseract/"; 65 66 private List<Language> mAvailable; 67 68 private LanguageAdapter mAdapter; 69 70 private ListView mListView; 71 72 private File mTessdata; 73 74 private IntentFilter mFilter; 75 76 private IntentFilter mFilter2; 77 78 private SharedPreferences mPrefs; 79 80 private Ocr mOcr; 81 82 private boolean mInitialized = false; 83 84 @Override 85 protected void onCreate(Bundle savedInstanceState) { 86 super.onCreate(savedInstanceState); 87 88 mFilter = new IntentFilter(); 89 mFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 90 mFilter.addDataScheme("file"); 91 92 mFilter2 = new IntentFilter(); 93 mFilter2.addAction(Intents.Actions.LANGUAGES_UPDATED); 94 95 mPrefs = getPreferences(MODE_PRIVATE); 96 97 mAdapter = new LanguageAdapter(this); 98 mAdapter.setNotifyOnChange(true); 99 100 Ocr.InitCallback initCallback = new Ocr.InitCallback() { 101 @Override 102 public void onInitialized(int status) { 103 updateLanguages(); 104 105 mInitialized = true; 106 } 107 }; 108 109 mOcr = new Ocr(this, initCallback, true); 110 111 onConfigurationChanged(getResources().getConfiguration()); 112 } 113 114 @Override 115 public void onConfigurationChanged(Configuration newConfig) { 116 super.onConfigurationChanged(newConfig); 117 118 setContentView(R.layout.manage); 119 120 mListView = (ListView) findViewById(R.id.list_languages); 121 mListView.setAdapter(mAdapter); 122 mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 123 mListView.setOnItemClickListener(itemClickListener); 124 } 125 126 @Override 127 protected void onResume() { 128 super.onResume(); 129 130 if (mInitialized) { 131 updateLanguages(); 132 } 133 134 registerReceiver(broadcastReceiver, mFilter); 135 registerReceiver(broadcastReceiver, mFilter2); 136 } 137 138 @Override 139 protected void onPause() { 140 unregisterReceiver(broadcastReceiver); 141 142 super.onPause(); 143 } 144 145 @Override 146 public void onDestroy() { 147 mOcr.release(); 148 149 super.onDestroy(); 150 } 151 152 private void updateLanguages() { 153 mTessdata = mOcr.getTessdata(); 154 mAvailable = mOcr.getAvailableLanguages(); 155 156 final String xmlPref = getString(R.string.xml_cache_pref); 157 final String cachedXml = mPrefs.getString(xmlPref, null); 158 159 new XmlLoader(this, mAvailable) { 160 @Override 161 protected void onPostExecute(final TreeSet<LanguageData> result) { 162 // Show results on-screen 163 onLoad(result); 164 165 // Cache resulting XML in preferences 166 if (result != null) { 167 final String cachedXml = getCachedXml(); 168 169 if (cachedXml != null) { 170 final SharedPreferences.Editor editor = mPrefs.edit(); 171 editor.putString(xmlPref, cachedXml); 172 editor.commit(); 173 } 174 } 175 176 super.onPostExecute(result); 177 } 178 }.setCachedXml(cachedXml).execute(XML_SOURCE); 179 } 180 181 private void onLoad(TreeSet<LanguageData> languages) { 182 if (languages == null) { 183 Toast.makeText(this, R.string.manage_error, Toast.LENGTH_LONG).show(); 184 return; 185 } 186 187 mAdapter.clear(); 188 mAdapter.addAll(languages); 189 190 } 191 192 private void showConfirm(String text, DialogInterface.OnClickListener onClick) { 193 Dialog dialog = new AlertDialog.Builder(this).setCancelable(true).setMessage(text) 194 .setPositiveButton(getString(android.R.string.yes), onClick) 195 .setNegativeButton(getString(android.R.string.cancel), null).create(); 196 197 dialog.setOwnerActivity(this); 198 dialog.show(); 199 } 200 201 private void installLanguage(final LanguageData data) { 202 Log.i(TAG, "Installing " + data.name + "..."); 203 204 new LanguageLoader(this, DATA_SOURCE, mTessdata) { 205 @Override 206 protected void onPostExecute(final LanguageData result) { 207 // Show results on-screen 208 onInstall(result, getCanceled()); 209 210 super.onPostExecute(result); 211 } 212 }.execute(data); 213 } 214 215 private void onInstall(LanguageData data, boolean canceled) { 216 int resId; 217 218 if (data != null) { 219 data.installed = true; 220 mAdapter.notifyDataSetChanged(); 221 mOcr.reloadLanguages(); 222 223 resId = R.string.install_completed; 224 } else if (canceled) { 225 resId = R.string.install_canceled; 226 } else { 227 resId = R.string.install_failed; 228 } 229 230 String message = getString(resId, data.name); 231 Toast.makeText(this, message, Toast.LENGTH_LONG).show(); 232 } 233 234 private void promptUninstallLanguage(final LanguageData data) { 235 DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() { 236 @Override 237 public void onClick(DialogInterface dialog, int which) { 238 if (which == DialogInterface.BUTTON_POSITIVE) { 239 Thread uninstaller = new Thread() { 240 @Override 241 public void run() { 242 uninstallLanguageAsync(data); 243 } 244 }; 245 uninstaller.start(); 246 } 247 } 248 }; 249 250 String message = getString(R.string.uninstall_confirm, data.name); 251 showConfirm(message, onClickListener); 252 } 253 254 private void uninstallLanguageAsync(final LanguageData data) { 255 final File installed = new File(mTessdata, data.iso6392 + ".traineddata"); 256 final boolean success = installed.delete(); 257 258 runOnUiThread(new Runnable() { 259 @Override 260 public void run() { 261 onUninstall(data, success); 262 } 263 }); 264 } 265 266 private void onUninstall(LanguageData data, boolean success) { 267 int resId; 268 269 if (success) { 270 data.installed = false; 271 mAdapter.notifyDataSetChanged(); 272 mOcr.reloadLanguages(); 273 274 resId = R.string.uninstall_completed; 275 } else { 276 resId = R.string.uninstall_failed; 277 } 278 279 String message = getString(resId, data.name); 280 Toast.makeText(this, message, Toast.LENGTH_LONG).show(); 281 } 282 283 private class LanguageAdapter extends ArrayAdapter<LanguageData> { 284 private final int mColorRed; 285 286 public LanguageAdapter(Context context) { 287 super(context, 0); 288 289 mColorRed = context.getResources().getColor(R.color.red); 290 } 291 292 @Override 293 public View getView(int position, View convertView, ViewGroup parent) { 294 LanguageData data = getItem(position); 295 296 LayoutInflater inflate = LayoutInflater.from(getContext()); 297 View view = inflate.inflate(R.layout.language, null); 298 ((TextView) view.findViewById(R.id.text_size)).setText(data.size); 299 ((TextView) view.findViewById(R.id.text_iso6392)).setText(data.iso6392); 300 ((TextView) view.findViewById(R.id.text_name)).setText(data.name); 301 302 TextView installed = ((TextView) view.findViewById(R.id.text_installed)); 303 installed.setText(data.installed ? R.string.installed : R.string.not_installed); 304 305 if (!data.installed) { 306 installed.setTextColor(mColorRed); 307 } 308 309 return view; 310 } 311 312 public void addAll(Collection<? extends LanguageData> items) { 313 for (LanguageData item : items) { 314 add(item); 315 } 316 } 317 } 318 319 static class LanguageData implements Comparable<LanguageData> { 320 String size; 321 String file; 322 String iso6392; 323 String name; 324 325 boolean installed; 326 boolean hidden; 327 328 @Override 329 public int compareTo(LanguageData another) { 330 return name.compareTo(another.name); 331 } 332 } 333 334 private final OnItemClickListener itemClickListener = new OnItemClickListener() { 335 @Override 336 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 337 LanguageData data = mAdapter.getItem(position); 338 339 if (data == null) { 340 return; 341 } 342 343 if (!data.installed) { 344 installLanguage(data); 345 } else { 346 promptUninstallLanguage(data); 347 } 348 } 349 }; 350 351 private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 352 @Override 353 public void onReceive(Context context, Intent intent) { 354 if (intent.getAction().equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 355 finish(); 356 } else if (mInitialized 357 && intent.getAction().equals(Intents.Actions.LANGUAGES_UPDATED)) { 358 updateLanguages(); 359 } 360 } 361 }; 362}