X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=android%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fandroid%2FDecodeThread.java;h=75e5bad74da92cb40fa39040d984689c7bdaa28f;hb=b320f70e522f4f2c126cf2e3ff5d8db7b64fb62c;hp=2c4b904099d413d2650df1bab4dbb84d96913501;hpb=ccd03e3e57b3cc0c7f65b9c4239d9c2976c4297d;p=zxing.git diff --git a/android/src/com/google/zxing/client/android/DecodeThread.java b/android/src/com/google/zxing/client/android/DecodeThread.java old mode 100644 new mode 100755 index 2c4b9040..75e5bad7 --- a/android/src/com/google/zxing/client/android/DecodeThread.java +++ b/android/src/com/google/zxing/client/android/DecodeThread.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Google Inc. + * Copyright (C) 2008 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,206 +16,81 @@ package com.google.zxing.client.android; -import android.app.Application; -import android.graphics.Bitmap; -import android.os.Debug; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; import com.google.zxing.BarcodeFormat; import com.google.zxing.DecodeHintType; -import com.google.zxing.MonochromeBitmapSource; -import com.google.zxing.MultiFormatReader; -import com.google.zxing.ReaderException; -import com.google.zxing.Result; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Date; +import com.google.zxing.ResultPointCallback; + +import android.content.SharedPreferences; +import android.os.Handler; +import android.os.Looper; +import android.preference.PreferenceManager; + import java.util.Hashtable; import java.util.Vector; +import java.util.concurrent.CountDownLatch; /** - * This thread does all the heavy lifting of decoding the images. It can also save images to flash - * for debugging purposes. + * This thread does all the heavy lifting of decoding the images. * * @author dswitkin@google.com (Daniel Switkin) */ final class DecodeThread extends Thread { - public Handler handler; + public static final String BARCODE_BITMAP = "barcode_bitmap"; - private final BarcodeReaderCaptureActivity activity; - private final CameraManager cameraManager; - private Hashtable hints; - private Handler cameraThreadHandler; - private int methodTraceCount; - private boolean tracing; - - DecodeThread(BarcodeReaderCaptureActivity activity, CameraManager cameraManager) { - this.activity = activity; - this.cameraManager = cameraManager; - methodTraceCount = 0; - tracing = false; - } - - @Override - public void run() { - Looper.prepare(); - handler = new Handler() { - public void handleMessage(Message message) { - switch (message.what) { - case R.id.decode: - captureAndDecode(); - break; - case R.id.save: - captureAndSave(); - break; - case R.id.quit: - Looper.myLooper().quit(); - break; - case R.id.set_decode_all_mode: - setDecodeAllMode(); - break; - case R.id.set_decode_1D_mode: - setDecode1DMode(); - break; - case R.id.set_decode_QR_mode: - setDecodeQRMode(); - break; - case R.id.toggle_tracing: - tracing = !tracing; - break; - } - } - }; - Looper.loop(); - } + private final CaptureActivity activity; + private final Hashtable hints; + private Handler handler; + private final CountDownLatch handlerInitLatch; - public void setCameraThreadHandler(Handler cameraThreadHandler) { - this.cameraThreadHandler = cameraThreadHandler; - } + DecodeThread(CaptureActivity activity, + Vector decodeFormats, + String characterSet, + ResultPointCallback resultPointCallback) { - private void setDecodeAllMode() { - hints = null; - } + this.activity = activity; + handlerInitLatch = new CountDownLatch(1); - // TODO: This is fragile in case we add new formats. It would be better to have a new enum - // value which represented all 1D formats. - private void setDecode1DMode() { hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.UPC_A); - vector.addElement(BarcodeFormat.UPC_E); - vector.addElement(BarcodeFormat.EAN_13); - vector.addElement(BarcodeFormat.EAN_8); - vector.addElement(BarcodeFormat.CODE_39); - vector.addElement(BarcodeFormat.CODE_128); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - } - private void setDecodeQRMode() { - hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.QR_CODE); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - } - - private void captureAndDecode() { - Date startDate = new Date(); - Bitmap bitmap = cameraManager.captureStill(); - // Let the CameraThread know it can resume previews while the decoding continues in parallel. - Message restart = Message.obtain(cameraThreadHandler, R.id.decode_started); - restart.sendToTarget(); - - if (tracing) { - Debug.startMethodTracing("/sdcard/ZXingDecodeThread" + methodTraceCount); - methodTraceCount++; - } - boolean success; - Result rawResult = null; - try { - MonochromeBitmapSource source = new RGBMonochromeBitmapSource(bitmap); - rawResult = new MultiFormatReader().decode(source, hints); - success = true; - } catch (ReaderException e) { - success = false; - } - if (tracing) { - Debug.stopMethodTracing(); - } - Date endDate = new Date(); - - if (success) { - Message message = Message.obtain(cameraThreadHandler, R.id.decode_succeeded, rawResult); - message.arg1 = (int) (endDate.getTime() - startDate.getTime()); - message.sendToTarget(); + // The prefs can't change while the thread is running, so pick them up once here. + if (decodeFormats == null || decodeFormats.isEmpty()) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + boolean decode1D = prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, true); + boolean decodeQR = prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, true); + if (decode1D && decodeQR) { + hints.put(DecodeHintType.POSSIBLE_FORMATS, CaptureActivity.ALL_FORMATS); + } else if (decode1D) { + hints.put(DecodeHintType.POSSIBLE_FORMATS, CaptureActivity.ONE_D_FORMATS); + } else if (decodeQR) { + hints.put(DecodeHintType.POSSIBLE_FORMATS, CaptureActivity.QR_CODE_FORMATS); + } } else { - Message message = Message.obtain(cameraThreadHandler, R.id.decode_failed); - message.sendToTarget(); + hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats); } - } - /** - * This is a debugging feature used to take photos and save them as JPEGs using the exact camera - * setup as in normal decoding. This is useful for building up a library of test images. - */ - private void captureAndSave() { - Bitmap bitmap = cameraManager.captureStill(); - OutputStream outStream = getNewPhotoOutputStream(); - if (outStream != null) { - bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outStream); - try { - outStream.close(); - } catch (IOException e) { - } - Message success = Message.obtain(cameraThreadHandler, R.id.save_succeeded); - success.sendToTarget(); - } else { - Message failure = Message.obtain(cameraThreadHandler, R.id.save_failed); - failure.sendToTarget(); + if (characterSet != null) { + hints.put(DecodeHintType.CHARACTER_SET, characterSet); } + + hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback); } - /** - * We prefer to write to the SD Card because it has more space, and is automatically mounted as a - * drive over USB. If it's not present, fall back to the package's private file area here: - * - * /data/data/com.google.zxing.client.android/files - * - * @return A stream which represents the new file where the photo will be saved. - */ - private OutputStream getNewPhotoOutputStream() { - File sdcard = new File("/sdcard"); - if (sdcard.exists()) { - File barcodes = new File(sdcard, "barcodes"); - if (!barcodes.exists()) { - if (!barcodes.mkdir()) { - return null; - } - } - String fileName = getNewPhotoName(); - try { - return new FileOutputStream(new File(barcodes, fileName)); - } catch (FileNotFoundException e) { - } - } else { - Application application = activity.getApplication(); - String fileName = getNewPhotoName(); - try { - return application.openFileOutput(fileName, 0); - } catch (FileNotFoundException e) { - } + Handler getHandler() { + try { + handlerInitLatch.await(); + } catch (InterruptedException ie) { + // continue? } - return null; + return handler; } - private String getNewPhotoName() { - Date now = new Date(); - return "capture" + now.getTime() + ".jpg"; + @Override + public void run() { + Looper.prepare(); + handler = new DecodeHandler(activity, hints); + handlerInitLatch.countDown(); + Looper.loop(); } }