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 com.google.zxing.Result;
20 import com.google.zxing.ResultPoint;
21 import com.google.zxing.client.result.ParsedReaderResult;
22 import com.google.zxing.client.result.ParsedReaderResultType;
24 import android.app.Activity;
25 import android.content.Context;
26 import android.graphics.PixelFormat;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.Message;
30 import android.view.KeyEvent;
31 import android.view.Menu;
32 import android.view.Window;
33 import android.view.WindowManager.LayoutParams;
35 public final class BarcodeReaderCaptureActivity extends Activity {
37 private CameraManager cameraManager;
38 private CameraSurfaceView surfaceView;
39 private WorkerThread workerThread;
41 private static final int ABOUT_ID = Menu.FIRST;
44 public void onCreate(Bundle icicle) {
45 super.onCreate(icicle);
46 requestWindowFeature(Window.FEATURE_NO_TITLE);
48 // Make sure to create a TRANSLUCENT window. This is required for SurfaceView to work.
49 // Eventually this'll be done by the system automatically.
50 getWindow().setAttributes(new LayoutParams(LayoutParams.APPLICATION_TYPE,
51 LayoutParams.NO_STATUS_BAR_FLAG));
52 getWindow().setFormat(PixelFormat.TRANSLUCENT);
54 cameraManager = new CameraManager(getApplication());
55 surfaceView = new CameraSurfaceView(getApplication(), cameraManager);
56 setContentView(surfaceView);
57 workerThread = new WorkerThread(surfaceView, cameraManager, messageHandler);
58 workerThread.requestPreviewLoop();
63 protected boolean isFullscreenOpaque() {
64 // Our main window is set to translucent, but we know that we will
65 // fill it with opaque data. Tell the system that so it can perform
66 // some important optimizations.
71 protected void onResume() {
73 cameraManager.openDriver();
74 if (workerThread == null) {
75 workerThread = new WorkerThread(surfaceView, cameraManager, messageHandler);
76 workerThread.requestPreviewLoop();
82 protected void onPause() {
84 if (workerThread != null) {
85 workerThread.requestExitAndWait();
88 cameraManager.closeDriver();
92 public boolean onKeyDown(int keyCode, KeyEvent event) {
93 if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
94 workerThread.requestStillAndDecode();
97 return super.onKeyDown(keyCode, event);
102 public boolean onCreateOptionsMenu(Menu menu) {
103 super.onCreateOptionsMenu(menu);
104 menu.add(0, ABOUT_ID, R.string.menu_about);
109 public boolean onOptionsItemSelected(Menu.Item item) {
110 switch (item.getId()) {
112 Context context = getApplication();
113 showAlert(context.getString(R.string.title_about),
114 context.getString(R.string.msg_about),
115 context.getString(R.string.button_ok), null, true, null);
118 return super.onOptionsItemSelected(item);
121 Handler messageHandler = new Handler() {
123 public void handleMessage(Message message) {
124 switch (message.what) {
125 case R.id.decoding_succeeded_message:
126 handleDecode((Result)message.obj);
128 case R.id.decoding_failed_message:
129 Context context = getApplication();
130 showAlert(context.getString(R.string.title_no_barcode_detected),
131 context.getString(R.string.msg_no_barcode_detected),
132 context.getString(R.string.button_ok), null, true, null);
138 public void restartPreview() {
139 workerThread.requestPreviewLoop();
142 // TODO(dswitkin): These deprecated showAlert calls need to be updated.
143 private void handleDecode(Result rawResult) {
144 ResultPoint[] points = rawResult.getResultPoints();
145 if (points != null && points.length > 0) {
146 surfaceView.drawResultPoints(points);
149 Context context = getApplication();
150 ParsedReaderResult readerResult = ParsedReaderResult.parseReaderResult(rawResult.getText());
151 Handler handler = new ResultHandler(this, readerResult);
152 if (canBeHandled(readerResult.getType())) {
153 // Can be handled by some external app; ask if the user wants to
154 // proceed first though
155 Message yesMessage = handler.obtainMessage(R.string.button_yes);
156 Message noMessage = handler.obtainMessage(R.string.button_no);
157 showAlert(context.getString(getDialogTitleID(readerResult.getType())),
158 readerResult.getDisplayResult(), context.getString(R.string.button_yes),
159 yesMessage, context.getString(R.string.button_no), noMessage, true, noMessage);
161 // Just show information to user
162 Message okMessage = handler.obtainMessage(R.string.button_ok);
163 showAlert(context.getString(R.string.title_barcode_detected),
164 readerResult.getDisplayResult(), context.getString(R.string.button_ok), okMessage, null,
165 null, true, okMessage);
169 private static boolean canBeHandled(ParsedReaderResultType type) {
170 return type != ParsedReaderResultType.TEXT;
173 private static int getDialogTitleID(ParsedReaderResultType type) {
174 if (type == ParsedReaderResultType.ADDRESSBOOK) {
175 return R.string.title_add_contact;
176 } else if (type == ParsedReaderResultType.BOOKMARK) {
177 return R.string.title_open_url;
178 } else if (type == ParsedReaderResultType.EMAIL || type == ParsedReaderResultType.EMAIL_ADDRESS) {
179 return R.string.title_compose_email;
180 } else if (type == ParsedReaderResultType.UPC) {
181 return R.string.title_lookup_barcode;
182 } else if (type == ParsedReaderResultType.URI) {
183 return R.string.title_open_url;
185 return R.string.title_barcode_detected;