2 * Copyright 2008 ZXing authors
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() {
61 public void handleMessage(Message message) {
62 switch (message.what) {
64 if (state == State.PREVIEW) {
65 surfaceView.capturePreviewAndDraw();
70 Message save = Message.obtain(decodeThread.handler, R.id.save);
73 case R.id.restart_preview:
74 restartPreviewAndDecode();
78 Message quit = Message.obtain(decodeThread.handler, R.id.quit);
82 } catch (InterruptedException e) {
84 Looper.myLooper().quit();
86 case R.id.decode_started:
87 // Since the decoder is done with the camera, continue fetching preview frames.
88 state = State.PREVIEW;
90 case R.id.decode_succeeded:
92 // Message.copyFrom() did not work as expected, hence this workaround.
93 Message success = Message.obtain(activityHandler, R.id.decode_succeeded, message.obj);
94 success.arg1 = message.arg1;
95 success.sendToTarget();
97 case R.id.decode_failed:
98 // We're decoding as fast as possible, so when one fails, start another.
101 case R.id.save_succeeded:
102 // TODO: Put up a non-blocking status message
103 restartPreviewAndDecode();
105 case R.id.save_failed:
106 // TODO: Put up a blocking error message
107 restartPreviewAndDecode();
111 if (state == State.PREVIEW) {
112 Message preview = Message.obtain(handler, R.id.preview);
113 preview.sendToTarget();
117 decodeThread.setCameraThreadHandler(handler);
119 // Start ourselves capturing previews
120 restartPreviewAndDecode();
124 public void quitSynchronously() {
125 Message quit = Message.obtain(handler, R.id.quit);
129 } catch (InterruptedException e) {
133 public void setDecodeAllMode() {
134 Message message = Message.obtain(decodeThread.handler, R.id.set_decode_all_mode);
135 message.sendToTarget();
138 public void setDecode1DMode() {
139 Message message = Message.obtain(decodeThread.handler, R.id.set_decode_1D_mode);
140 message.sendToTarget();
143 public void setDecodeQRMode() {
144 Message message = Message.obtain(decodeThread.handler, R.id.set_decode_QR_mode);
145 message.sendToTarget();
148 public void toggleTracing() {
149 Message message = Message.obtain(decodeThread.handler, R.id.toggle_tracing);
150 message.sendToTarget();
154 * Start a decode if possible, but not now if the DecodeThread is in the middle of saving.
156 private void startDecode() {
157 if (state != State.SAVE) {
158 state = State.DECODE;
159 Message decode = Message.obtain(decodeThread.handler, R.id.decode);
160 decode.sendToTarget();
165 * Take one preview to update the screen, then do a decode and continue previews.
167 private void restartPreviewAndDecode() {
168 state = State.PREVIEW;
169 surfaceView.capturePreviewAndDraw();