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.os.Handler;
20 import android.os.Looper;
21 import android.os.Message;
24 * This thread continuously pulls preview frames from the camera and draws them to the screen. It
25 * also asks the DecodeThread to process as many images as it can keep up with, and coordinates with
26 * the main thread to display the results.
28 * @author dswitkin@google.com (Daniel Switkin)
30 final class CameraThread extends Thread {
32 public Handler handler;
34 private final CameraSurfaceView surfaceView;
35 private final Handler activityHandler;
36 private final DecodeThread decodeThread;
46 CameraThread(BarcodeReaderCaptureActivity activity, CameraSurfaceView surfaceView,
47 CameraManager cameraManager, Handler activityHandler) {
48 this.surfaceView = surfaceView;
49 this.activityHandler = activityHandler;
51 decodeThread = new DecodeThread(activity, cameraManager);
59 handler = new Handler() {
60 public void handleMessage(Message message) {
61 switch (message.what) {
63 if (state == State.PREVIEW) {
64 surfaceView.capturePreviewAndDraw();
69 Message save = Message.obtain(decodeThread.handler, R.id.save);
72 case R.id.restart_preview:
73 restartPreviewAndDecode();
77 Message quit = Message.obtain(decodeThread.handler, R.id.quit);
81 } catch (InterruptedException e) {
83 Looper.myLooper().quit();
85 case R.id.decode_started:
86 // Since the decoder is done with the camera, continue fetching preview frames.
87 state = State.PREVIEW;
89 case R.id.decode_succeeded:
91 // Message.copyFrom() did not work as expected, hence this workaround.
92 Message success = Message.obtain(activityHandler, R.id.decode_succeeded, message.obj);
93 success.arg1 = message.arg1;
94 success.sendToTarget();
96 case R.id.decode_failed:
97 // We're decoding as fast as possible, so when one fails, start another.
100 case R.id.save_succeeded:
101 // TODO: Put up a non-blocking status message
102 restartPreviewAndDecode();
104 case R.id.save_failed:
105 // TODO: Put up a blocking error message
106 restartPreviewAndDecode();
110 if (state == State.PREVIEW) {
111 Message preview = Message.obtain(handler, R.id.preview);
112 preview.sendToTarget();
116 decodeThread.setCameraThreadHandler(handler);
118 // Start ourselves capturing previews
119 restartPreviewAndDecode();
123 public void quitSynchronously() {
124 Message quit = Message.obtain(handler, R.id.quit);
128 } catch (InterruptedException e) {
132 public void setDecodeAllMode() {
133 Message message = Message.obtain(decodeThread.handler, R.id.set_decode_all_mode);
134 message.sendToTarget();
137 public void setDecode1DMode() {
138 Message message = Message.obtain(decodeThread.handler, R.id.set_decode_1D_mode);
139 message.sendToTarget();
142 public void setDecodeQRMode() {
143 Message message = Message.obtain(decodeThread.handler, R.id.set_decode_QR_mode);
144 message.sendToTarget();
147 public void toggleTracing() {
148 Message message = Message.obtain(decodeThread.handler, R.id.toggle_tracing);
149 message.sendToTarget();
153 * Start a decode if possible, but not now if the DecodeThread is in the middle of saving.
155 private void startDecode() {
156 if (state != State.SAVE) {
157 state = State.DECODE;
158 Message decode = Message.obtain(decodeThread.handler, R.id.decode);
159 decode.sendToTarget();
164 * Take one preview to update the screen, then do a decode and continue previews.
166 private void restartPreviewAndDecode() {
167 state = State.PREVIEW;
168 surfaceView.capturePreviewAndDraw();