17620644768ffc235607b3a94671e49518c18686fBryan Mawhinney/* 27620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * Copyright (C) 2008 ZXing authors 37620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * 47620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * Licensed under the Apache License, Version 2.0 (the "License"); 57620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * you may not use this file except in compliance with the License. 67620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * You may obtain a copy of the License at 77620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * 87620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * http://www.apache.org/licenses/LICENSE-2.0 97620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * 107620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * Unless required by applicable law or agreed to in writing, software 117620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * distributed under the License is distributed on an "AS IS" BASIS, 127620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * See the License for the specific language governing permissions and 147620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * limitations under the License. 157620644768ffc235607b3a94671e49518c18686fBryan Mawhinney */ 167620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 177620644768ffc235607b3a94671e49518c18686fBryan Mawhinneypackage com.google.zxing.client.android; 187620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 197620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport com.google.zxing.Result; 207620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport com.google.zxing.client.android.camera.CameraManager; 217620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 227620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport android.app.Activity; 237620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport android.content.Intent; 247620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport android.graphics.Bitmap; 257620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport android.net.Uri; 267620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport android.os.Bundle; 277620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport android.os.Handler; 287620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport android.os.Message; 297620644768ffc235607b3a94671e49518c18686fBryan Mawhinneyimport android.util.Log; 307620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 317620644768ffc235607b3a94671e49518c18686fBryan Mawhinney/** 327620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * This class handles all the messaging which comprises the state machine for capture. 337620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * 347620644768ffc235607b3a94671e49518c18686fBryan Mawhinney * @author dswitkin@google.com (Daniel Switkin) 357620644768ffc235607b3a94671e49518c18686fBryan Mawhinney */ 367620644768ffc235607b3a94671e49518c18686fBryan Mawhinneypublic final class CaptureActivityHandler extends Handler { 377620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 387620644768ffc235607b3a94671e49518c18686fBryan Mawhinney private static final String TAG = CaptureActivityHandler.class.getSimpleName(); 397620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 407620644768ffc235607b3a94671e49518c18686fBryan Mawhinney private final CaptureActivity activity; 417620644768ffc235607b3a94671e49518c18686fBryan Mawhinney private final DecodeThread decodeThread; 427620644768ffc235607b3a94671e49518c18686fBryan Mawhinney private State state; 437620644768ffc235607b3a94671e49518c18686fBryan Mawhinney private final CameraManager cameraManager; 447620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 457620644768ffc235607b3a94671e49518c18686fBryan Mawhinney private enum State { 467620644768ffc235607b3a94671e49518c18686fBryan Mawhinney PREVIEW, 477620644768ffc235607b3a94671e49518c18686fBryan Mawhinney SUCCESS, 487620644768ffc235607b3a94671e49518c18686fBryan Mawhinney DONE 497620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 507620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 517620644768ffc235607b3a94671e49518c18686fBryan Mawhinney CaptureActivityHandler(CaptureActivity activity, 527620644768ffc235607b3a94671e49518c18686fBryan Mawhinney String characterSet, 537620644768ffc235607b3a94671e49518c18686fBryan Mawhinney CameraManager cameraManager) { 547620644768ffc235607b3a94671e49518c18686fBryan Mawhinney this.activity = activity; 557620644768ffc235607b3a94671e49518c18686fBryan Mawhinney decodeThread = new DecodeThread(activity, characterSet, 567620644768ffc235607b3a94671e49518c18686fBryan Mawhinney new ViewfinderResultPointCallback(activity.getViewfinderView())); 577620644768ffc235607b3a94671e49518c18686fBryan Mawhinney decodeThread.start(); 587620644768ffc235607b3a94671e49518c18686fBryan Mawhinney state = State.SUCCESS; 597620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 607620644768ffc235607b3a94671e49518c18686fBryan Mawhinney // Start ourselves capturing previews and decoding. 617620644768ffc235607b3a94671e49518c18686fBryan Mawhinney this.cameraManager = cameraManager; 627620644768ffc235607b3a94671e49518c18686fBryan Mawhinney cameraManager.startPreview(); 637620644768ffc235607b3a94671e49518c18686fBryan Mawhinney restartPreviewAndDecode(); 647620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 657620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 667620644768ffc235607b3a94671e49518c18686fBryan Mawhinney @Override 677620644768ffc235607b3a94671e49518c18686fBryan Mawhinney public void handleMessage(Message message) { 687620644768ffc235607b3a94671e49518c18686fBryan Mawhinney if (message.what == R.id.auto_focus) { 697620644768ffc235607b3a94671e49518c18686fBryan Mawhinney //Log.d(TAG, "Got auto-focus message"); 707620644768ffc235607b3a94671e49518c18686fBryan Mawhinney // When one auto focus pass finishes, start another. This is the closest thing to 717620644768ffc235607b3a94671e49518c18686fBryan Mawhinney // continuous AF. It does seem to hunt a bit, but I'm not sure what else to do. 727620644768ffc235607b3a94671e49518c18686fBryan Mawhinney if (state == State.PREVIEW) { 737620644768ffc235607b3a94671e49518c18686fBryan Mawhinney cameraManager.requestAutoFocus(this, R.id.auto_focus); 747620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 757620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } else if (message.what == R.id.restart_preview) { 767620644768ffc235607b3a94671e49518c18686fBryan Mawhinney Log.d(TAG, "Got restart preview message"); 777620644768ffc235607b3a94671e49518c18686fBryan Mawhinney restartPreviewAndDecode(); 787620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } else if (message.what == R.id.decode_succeeded) { 797620644768ffc235607b3a94671e49518c18686fBryan Mawhinney Log.d(TAG, "Got decode succeeded message"); 807620644768ffc235607b3a94671e49518c18686fBryan Mawhinney state = State.SUCCESS; 817620644768ffc235607b3a94671e49518c18686fBryan Mawhinney Bundle bundle = message.getData(); 827620644768ffc235607b3a94671e49518c18686fBryan Mawhinney Bitmap barcode = bundle == null ? null : 837620644768ffc235607b3a94671e49518c18686fBryan Mawhinney (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP); 847620644768ffc235607b3a94671e49518c18686fBryan Mawhinney activity.handleDecode((Result) message.obj, barcode); 857620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } else if (message.what == R.id.decode_failed) { 867620644768ffc235607b3a94671e49518c18686fBryan Mawhinney // We're decoding as fast as possible, so when one decode fails, start another. 877620644768ffc235607b3a94671e49518c18686fBryan Mawhinney state = State.PREVIEW; 887620644768ffc235607b3a94671e49518c18686fBryan Mawhinney cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode); 897620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } else if (message.what == R.id.return_scan_result) { 907620644768ffc235607b3a94671e49518c18686fBryan Mawhinney Log.d(TAG, "Got return scan result message"); 917620644768ffc235607b3a94671e49518c18686fBryan Mawhinney activity.setResult(Activity.RESULT_OK, (Intent) message.obj); 927620644768ffc235607b3a94671e49518c18686fBryan Mawhinney activity.finish(); 937620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } else if (message.what == R.id.launch_product_query) { 947620644768ffc235607b3a94671e49518c18686fBryan Mawhinney Log.d(TAG, "Got product query message"); 957620644768ffc235607b3a94671e49518c18686fBryan Mawhinney String url = (String) message.obj; 967620644768ffc235607b3a94671e49518c18686fBryan Mawhinney Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 977620644768ffc235607b3a94671e49518c18686fBryan Mawhinney intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 987620644768ffc235607b3a94671e49518c18686fBryan Mawhinney activity.startActivity(intent); 997620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 1007620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 1017620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 1027620644768ffc235607b3a94671e49518c18686fBryan Mawhinney public void quitSynchronously() { 1037620644768ffc235607b3a94671e49518c18686fBryan Mawhinney state = State.DONE; 1047620644768ffc235607b3a94671e49518c18686fBryan Mawhinney cameraManager.stopPreview(); 1057620644768ffc235607b3a94671e49518c18686fBryan Mawhinney Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit); 1067620644768ffc235607b3a94671e49518c18686fBryan Mawhinney quit.sendToTarget(); 1077620644768ffc235607b3a94671e49518c18686fBryan Mawhinney try { 1087620644768ffc235607b3a94671e49518c18686fBryan Mawhinney // Wait at most half a second; should be enough time, and onPause() will timeout quickly 1097620644768ffc235607b3a94671e49518c18686fBryan Mawhinney decodeThread.join(500L); 1107620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } catch (InterruptedException e) { 1117620644768ffc235607b3a94671e49518c18686fBryan Mawhinney // continue 1127620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 1137620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 1147620644768ffc235607b3a94671e49518c18686fBryan Mawhinney // Be absolutely sure we don't send any queued up messages 1157620644768ffc235607b3a94671e49518c18686fBryan Mawhinney removeMessages(R.id.decode_succeeded); 1167620644768ffc235607b3a94671e49518c18686fBryan Mawhinney removeMessages(R.id.decode_failed); 1177620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 1187620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 1197620644768ffc235607b3a94671e49518c18686fBryan Mawhinney private void restartPreviewAndDecode() { 1207620644768ffc235607b3a94671e49518c18686fBryan Mawhinney if (state == State.SUCCESS) { 1217620644768ffc235607b3a94671e49518c18686fBryan Mawhinney state = State.PREVIEW; 1227620644768ffc235607b3a94671e49518c18686fBryan Mawhinney cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode); 1237620644768ffc235607b3a94671e49518c18686fBryan Mawhinney cameraManager.requestAutoFocus(this, R.id.auto_focus); 1247620644768ffc235607b3a94671e49518c18686fBryan Mawhinney activity.drawViewfinder(); 1257620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 1267620644768ffc235607b3a94671e49518c18686fBryan Mawhinney } 1277620644768ffc235607b3a94671e49518c18686fBryan Mawhinney 1287620644768ffc235607b3a94671e49518c18686fBryan Mawhinney} 129