2 * Copyright (C) 2008 Google Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.google.zxing.client.android;
19 import android.app.Activity;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.os.Handler;
24 import android.os.Message;
25 import android.view.KeyEvent;
26 import android.view.Menu;
27 import android.view.Window;
28 import com.google.zxing.Result;
29 import com.google.zxing.ResultPoint;
30 import com.google.zxing.client.result.ParsedReaderResult;
31 import com.google.zxing.client.result.ParsedReaderResultType;
34 * The barcode reader activity itself. This is loosely based on the CameraPreview
35 * example included in the Android SDK.
37 * @author dswitkin@google.com (Daniel Switkin)
38 * @author Android Team (for CameraPreview example)
40 public final class BarcodeReaderCaptureActivity extends Activity {
42 private CameraManager cameraManager;
43 private CameraSurfaceView surfaceView;
44 private WorkerThread workerThread;
46 private static final int ABOUT_ID = Menu.FIRST;
49 public void onCreate(Bundle icicle) {
50 super.onCreate(icicle);
51 requestWindowFeature(Window.FEATURE_NO_TITLE);
53 cameraManager = new CameraManager(getApplication());
54 surfaceView = new CameraSurfaceView(getApplication(), cameraManager);
55 setContentView(surfaceView);
56 workerThread = new WorkerThread(surfaceView, cameraManager, messageHandler);
57 workerThread.requestPreviewLoop();
60 // TODO re-enable this when issues with Matrix.setPolyToPoly() are resolved
61 //GridSampler.setGridSampler(new AndroidGraphicsGridSampler());
65 protected void onResume() {
67 cameraManager.openDriver();
68 if (workerThread == null) {
69 workerThread = new WorkerThread(surfaceView, cameraManager, messageHandler);
70 workerThread.requestPreviewLoop();
76 protected void onPause() {
78 if (workerThread != null) {
79 workerThread.requestExitAndWait();
82 cameraManager.closeDriver();
86 public boolean onKeyDown(int keyCode, KeyEvent event) {
87 if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
88 workerThread.requestStillAndDecode();
91 return super.onKeyDown(keyCode, event);
96 public boolean onCreateOptionsMenu(Menu menu) {
97 super.onCreateOptionsMenu(menu);
98 menu.add(0, ABOUT_ID, R.string.menu_about);
103 public boolean onOptionsItemSelected(Menu.Item item) {
104 switch (item.getId()) {
106 Context context = getApplication();
108 context.getString(R.string.title_about),
110 context.getString(R.string.msg_about),
111 context.getString(R.string.button_ok),
115 return super.onOptionsItemSelected(item);
118 private final Handler messageHandler = new Handler() {
120 public void handleMessage(Message message) {
121 switch (message.what) {
122 case R.id.decoding_succeeded_message:
123 handleDecode((Result) message.obj);
125 case R.id.decoding_failed_message:
126 Context context = getApplication();
128 context.getString(R.string.title_no_barcode_detected),
130 context.getString(R.string.msg_no_barcode_detected),
131 context.getString(R.string.button_ok),
138 public void restartPreview() {
139 workerThread.requestPreviewLoop();
142 private void handleDecode(Result rawResult) {
143 ResultPoint[] points = rawResult.getResultPoints();
144 if (points != null && points.length > 0) {
145 surfaceView.drawResultPoints(points);
148 Context context = getApplication();
149 ParsedReaderResult readerResult = parseReaderResult(rawResult);
150 ResultHandler handler = new ResultHandler(this, readerResult);
151 if (handler.getIntent() != null) {
152 // Can be handled by some external app; ask if the user wants to
153 // proceed first though
155 context.getString(getDialogTitleID(readerResult.getType())),
157 readerResult.getDisplayResult(),
158 context.getString(R.string.button_yes),
160 context.getString(R.string.button_no),
167 // Just show information to user
169 context.getString(R.string.title_barcode_detected),
171 readerResult.getDisplayResult(),
172 context.getString(R.string.button_ok),
177 private static ParsedReaderResult parseReaderResult(Result rawResult) {
178 ParsedReaderResult readerResult = ParsedReaderResult.parseReaderResult(rawResult);
179 if (readerResult.getType().equals(ParsedReaderResultType.TEXT)) {
180 String rawText = rawResult.getText();
181 AndroidIntentParsedResult androidResult = AndroidIntentParsedResult.parse(rawText);
182 if (androidResult != null) {
183 Intent intent = androidResult.getIntent();
184 if (!Intent.VIEW_ACTION.equals(intent.getAction())) {
185 // For now, don't take anything that just parses as a View action. A lot
186 // of things are accepted as a View action by default.
187 readerResult = androidResult;
194 private static int getDialogTitleID(ParsedReaderResultType type) {
195 if (type.equals(ParsedReaderResultType.ADDRESSBOOK)) {
196 return R.string.title_add_contact;
197 } else if (type.equals(ParsedReaderResultType.URI) ||
198 type.equals(ParsedReaderResultType.BOOKMARK) ||
199 type.equals(ParsedReaderResultType.URLTO)) {
200 return R.string.title_open_url;
201 } else if (type.equals(ParsedReaderResultType.EMAIL) ||
202 type.equals(ParsedReaderResultType.EMAIL_ADDRESS)) {
203 return R.string.title_compose_email;
204 } else if (type.equals(ParsedReaderResultType.UPC)) {
205 return R.string.title_lookup_barcode;
206 } else if (type.equals(ParsedReaderResultType.TEL)) {
207 return R.string.title_dial;
208 } else if (type.equals(ParsedReaderResultType.GEO)) {
209 return R.string.title_view_maps;
211 return R.string.title_barcode_detected;