PageRenderTime 31ms CodeModel.GetById 16ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

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