/ItemID/src/com/ideal/itemid/ItemIdActivity.java

http://eyes-free.googlecode.com/ · Java · 235 lines · 178 code · 24 blank · 33 comment · 18 complexity · f21a57337b6d254bcc44d6f1db4d9274 MD5 · raw file

  1. /*
  2. * Copyright (C) 2010 The IDEAL Group
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of 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,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.ideal.itemid;
  17. import java.io.File;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.net.MalformedURLException;
  21. import java.net.URL;
  22. import java.net.URLConnection;
  23. import java.util.HashMap;
  24. import java.util.List;
  25. import android.app.Activity;
  26. import android.app.Dialog;
  27. import android.app.AlertDialog.Builder;
  28. import android.content.DialogInterface;
  29. import android.content.Intent;
  30. import android.content.pm.PackageManager;
  31. import android.content.pm.ResolveInfo;
  32. import android.media.MediaPlayer;
  33. import android.media.MediaPlayer.OnCompletionListener;
  34. import android.net.Uri;
  35. import android.os.Bundle;
  36. import android.speech.tts.TextToSpeech;
  37. import android.speech.tts.TextToSpeech.OnInitListener;
  38. import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
  39. /**
  40. * Main Activity for IDEAL Item ID. Enables users to scan a QR code or barcode.
  41. * If the user scans a QR code, reads out the contents of the QR code. If the
  42. * user scans a barcode, does a lookup for the UPC and speaks the result.
  43. */
  44. public class ItemIdActivity extends Activity {
  45. private TextToSpeech mTts;
  46. private HashMap<String, String> mTtsParams;
  47. private OnUtteranceCompletedListener mUtteranceCompletedListener = new OnUtteranceCompletedListener() {
  48. @Override
  49. public void onUtteranceCompleted(String utteranceId) {
  50. doScan();
  51. }
  52. };
  53. /** Called when the activity is first created. */
  54. @Override
  55. public void onCreate(Bundle savedInstanceState) {
  56. super.onCreate(savedInstanceState);
  57. if (!isBarcodeScannerInstalled()) {
  58. displayNoBarcodeScannerMessage();
  59. return;
  60. }
  61. setContentView(R.layout.main);
  62. mTtsParams = new HashMap<String, String>();
  63. // The utterance ID doesn't matter; we don't really care what was said,
  64. // just that the TTS has finished speaking.
  65. mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "done");
  66. mTts = new TextToSpeech(this, new OnInitListener() {
  67. @Override
  68. public void onInit(int arg0) {
  69. mTts.setOnUtteranceCompletedListener(mUtteranceCompletedListener);
  70. mTts.speak("Ready to scan", 0, mTtsParams);
  71. }
  72. });
  73. }
  74. @Override
  75. public void onDestroy() {
  76. super.onDestroy();
  77. if (mTts != null) {
  78. mTts.shutdown();
  79. }
  80. }
  81. // Checks if Barcode Scanner is installed.
  82. private boolean isBarcodeScannerInstalled() {
  83. Intent i = new Intent("android.intent.action.MAIN");
  84. i.setClassName("com.google.zxing.client.android",
  85. "com.google.zxing.client.android.CaptureActivity");
  86. List<ResolveInfo> list = getPackageManager().queryIntentActivities(i,
  87. PackageManager.MATCH_DEFAULT_ONLY);
  88. return list.size() > 0;
  89. }
  90. // Notifies the user that Barcode Scanner is not installed and provides a
  91. // way to easily find Barcode Scanner on Android Market.
  92. private void displayNoBarcodeScannerMessage() {
  93. Builder noBarcodeScannerMessage = new Builder(this);
  94. String titleText = "Warning: Barcode Scanner not found.";
  95. noBarcodeScannerMessage.setTitle(titleText);
  96. noBarcodeScannerMessage
  97. .setMessage("Ideal Item ID relies on Google's Barcode Scanner app. Please install Barcode Scanner to continue.");
  98. noBarcodeScannerMessage.setPositiveButton("Install Barcode Scanner",
  99. new Dialog.OnClickListener() {
  100. public void onClick(DialogInterface dialog, int which) {
  101. Intent i = new Intent(Intent.ACTION_VIEW);
  102. i.setData(Uri
  103. .parse("market://search?q=pname:com.google.zxing.client.android"));
  104. startActivity(i);
  105. finish();
  106. return;
  107. }
  108. });
  109. noBarcodeScannerMessage.setNegativeButton("Quit", new Dialog.OnClickListener() {
  110. public void onClick(DialogInterface dialog, int which) {
  111. finish();
  112. return;
  113. }
  114. });
  115. noBarcodeScannerMessage.setCancelable(false);
  116. noBarcodeScannerMessage.show();
  117. }
  118. // Invokes the Barcode Scanner using the ZXing Team's IntentIntegrator
  119. // class.
  120. private void doScan() {
  121. IntentIntegrator.initiateScan(this);
  122. }
  123. @Override
  124. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  125. if (resultCode == Activity.RESULT_CANCELED) {
  126. finish();
  127. return;
  128. }
  129. String content = data.getStringExtra("SCAN_RESULT");
  130. String format = data.getStringExtra("SCAN_RESULT_FORMAT");
  131. processResults(format, content);
  132. }
  133. // Handles the results from the Barcode Scanner.
  134. private void processResults(String format, String content) {
  135. if (IntentIntegrator.QR_CODE_TYPES.indexOf(format) != -1) {
  136. if (content.indexOf("audio://") == 0) {
  137. String filename = "/sdcard/idealItemId/" + content.replaceAll("audio://", "");
  138. if (new File(filename).exists()) {
  139. MediaPlayer mPlayer = MediaPlayer.create(this, Uri.parse(filename));
  140. mPlayer.setOnCompletionListener(new OnCompletionListener() {
  141. @Override
  142. public void onCompletion(MediaPlayer mp) {
  143. mp.release();
  144. doScan();
  145. }
  146. });
  147. mPlayer.start();
  148. } else {
  149. mTts.speak("Error: Unable to locate audio label on SD card.", 0, mTtsParams);
  150. }
  151. } else {
  152. mTts.speak(content, 0, mTtsParams);
  153. }
  154. } else {
  155. mTts.speak("Looking up barcode.", 0, null);
  156. HtmlDownloadJob currentJob = new HtmlDownloadJob("http://www.upcdatabase.com/item/"
  157. + content);
  158. currentJob.execute();
  159. }
  160. }
  161. // Callback to speak the item descrption after the UPC database lookup is
  162. // done.
  163. private void upcLookupDone(String itemDesc) {
  164. mTts.speak(itemDesc, 0, mTtsParams);
  165. }
  166. // Extracts the item description from the UPC database lookup results page.
  167. private class HtmlDownloadJob extends UserTask<Void, Void, String> {
  168. private String targetUrl;
  169. public HtmlDownloadJob(String target) {
  170. targetUrl = target;
  171. }
  172. @Override
  173. public String doInBackground(Void... params) {
  174. String itemDesc = "Item not found.";
  175. try {
  176. String pageUrl = targetUrl;
  177. // Download the HTML content
  178. URL url = new URL(pageUrl);
  179. URLConnection cn = url.openConnection();
  180. cn.connect();
  181. InputStream stream = cn.getInputStream();
  182. StringBuffer htmlContent = new StringBuffer();
  183. byte buf[] = new byte[16384];
  184. do {
  185. int numread = stream.read(buf);
  186. if (numread <= 0) {
  187. break;
  188. } else {
  189. htmlContent.append(new String(buf, 0, numread));
  190. }
  191. } while (true);
  192. String descStartWrapperText = "<tr><td>Description</td><td></td><td>";
  193. int descStart = htmlContent.indexOf(descStartWrapperText);
  194. if (descStart == -1) {
  195. return itemDesc;
  196. }
  197. descStart = descStart + descStartWrapperText.length();
  198. int descEnd = htmlContent.indexOf("</td>", descStart);
  199. itemDesc = htmlContent.substring(descStart, descEnd);
  200. } catch (MalformedURLException e) {
  201. } catch (IOException e) {
  202. } catch (OutOfMemoryError e) {
  203. }
  204. return itemDesc;
  205. }
  206. @Override
  207. public void onPostExecute(String itemDesc) {
  208. upcLookupDone(itemDesc);
  209. }
  210. }
  211. }