diff options
| author | Ralf Kistner <ralf@embarkmobile.com> | 2015-04-01 20:26:59 +0300 |
|---|---|---|
| committer | Ralf Kistner <ralf@embarkmobile.com> | 2015-04-01 20:26:59 +0300 |
| commit | 1c357625fbe685df10d62cee5f592ca3eb79c8f4 (patch) | |
| tree | 238a43e42ecf3db2ac379a8351722379c22ac7cb | |
| parent | 06088e84b2072c01ad204d1c7f932a7a2980bf0d (diff) | |
| download | zxing-android-embedded-1c357625fbe685df10d62cee5f592ca3eb79c8f4.tar.xz | |
Allow starting/stopping decoding without stopping preview.
| -rw-r--r-- | zxing-android/src/com/journeyapps/barcodescanner/BarcodeView.java | 92 | ||||
| -rw-r--r-- | zxing-android/src/com/journeyapps/barcodescanner/RotationListener.java | 4 |
2 files changed, 79 insertions, 17 deletions
diff --git a/zxing-android/src/com/journeyapps/barcodescanner/BarcodeView.java b/zxing-android/src/com/journeyapps/barcodescanner/BarcodeView.java index 3e40b167..be85ab86 100644 --- a/zxing-android/src/com/journeyapps/barcodescanner/BarcodeView.java +++ b/zxing-android/src/com/journeyapps/barcodescanner/BarcodeView.java @@ -53,6 +53,20 @@ public class BarcodeView extends ViewGroup { CONTINUOUS }; + public static enum PreviewScaleMode { + /** + * Center the preview inside the BarcodeView. It may contain black bars above and below, or + * left and right. + */ + CENTER, + + /** + * Drop the preview inside the BarcodeView (default). It will fill all available space, but sections may + * be cut off. + */ + CROP + }; + private static final String TAG = BarcodeView.class.getSimpleName(); private CameraInstance cameraInstance; @@ -69,10 +83,21 @@ public class BarcodeView extends ViewGroup { private SurfaceView surfaceView; + private boolean previewActive = false; + private RotationListener rotationListener; private List<StateListener> stateListeners = new ArrayList<>(); + private PreviewScaleMode previewScaleMode = PreviewScaleMode.CROP; + + private Rect containerRect; + private Point previewSize; + private Rect surfaceRect; + + private Rect framingRect = null; + private Rect previewFramingRect = null; + private final SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { @Override @@ -152,19 +177,29 @@ public class BarcodeView extends ViewGroup { } /** - * Call from UI thread only. + * Set the Decoder to use. Use this for more advanced customization of the decoding process, + * when Decoder#setReader() is not enough. * * The decoder's decode method will only be called from a dedicated DecoderThread. * + * Call this from UI thread only. + * * @param decoder the decoder used to decode barcodes. */ public void setDecoder(Decoder decoder) { + Util.validateMainThread(); + this.decoder = decoder; if(this.decoderThread != null) { this.decoderThread.setDecoder(decoder); } } + public Decoder getDecoder() { + return decoder; + } + + public void addStateListener(StateListener listener) { stateListeners.add(listener); } @@ -174,9 +209,17 @@ public class BarcodeView extends ViewGroup { listener.previewReady(); } } + public PreviewScaleMode getPreviewScaleMode() { + return previewScaleMode; + } - public Decoder getDecoder() { - return decoder; + /** + * Set the scale mode of the preview, when the aspect ratio is different from the BarcodeView. + * + * @param previewScaleMode PreviewScaleMode.CROP or PreviewScaleMode.CENTER + */ + public void setPreviewScaleMode(PreviewScaleMode previewScaleMode) { + this.previewScaleMode = previewScaleMode; } /** @@ -189,6 +232,7 @@ public class BarcodeView extends ViewGroup { public void decodeSingle(BarcodeCallback callback) { this.decodeMode = DecodeMode.SINGLE; this.callback = callback; + startDecoderThread(); } @@ -202,8 +246,12 @@ public class BarcodeView extends ViewGroup { public void decodeContinuous(BarcodeCallback callback) { this.decodeMode = DecodeMode.CONTINUOUS; this.callback = callback; + startDecoderThread(); } + /** + * Stop decoding, but do not stop the preview. + */ public void stopDecoding() { this.decodeMode = DecodeMode.NONE; this.callback = null; @@ -247,14 +295,6 @@ public class BarcodeView extends ViewGroup { return decoder; } - private boolean center = false; - - private Rect containerRect; - private Point previewSize; - private Rect surfaceRect; - - private Rect framingRect = null; - private Rect previewFramingRect = null; private void calculateFrames() { if(containerRect == null || previewSize == null) { @@ -270,7 +310,8 @@ public class BarcodeView extends ViewGroup { int width = containerRect.width(); int height = containerRect.height(); - + // Either crop or center the SurfaceView. + boolean center = (previewScaleMode == PreviewScaleMode.CENTER); if (center ^ (width * previewHeight < height * previewWidth)) { final int scaledChildWidth = previewWidth * height / previewHeight; surfaceRect = new Rect((width - scaledChildWidth) / 2, 0, (width + scaledChildWidth) / 2, height); @@ -347,6 +388,9 @@ public class BarcodeView extends ViewGroup { } /** + * Start the camera preview and decoding. Typically this should be called from the Activity's + * onResume() method. + * * Call from UI thread only. */ public void resume() { @@ -372,6 +416,9 @@ public class BarcodeView extends ViewGroup { /** + * Pause scanning and the camera preview. Typically this should be called from the Activity's + * onPause() method. + * * Call from UI thread only. */ public void pause() { @@ -383,6 +430,7 @@ public class BarcodeView extends ViewGroup { if(cameraInstance != null) { cameraInstance.close(); cameraInstance = null; + previewActive = false; } if (!hasSurface) { SurfaceHolder surfaceHolder = surfaceView.getHolder(); @@ -419,14 +467,24 @@ public class BarcodeView extends ViewGroup { } private void startCameraPreview(SurfaceHolder holder) { - cameraInstance.setSurfaceHolder(holder); - cameraInstance.startPreview(); + if(!previewActive) { + Log.i(TAG, "Starting preview"); + cameraInstance.setSurfaceHolder(holder); + cameraInstance.startPreview(); + previewActive = true; + } + startDecoderThread(); + } + + private void startDecoderThread() { stopDecoderThread(); // To be safe - decoderThread = new DecoderThread(cameraInstance, decoder, resultHandler); - decoderThread.setCropRect(previewFramingRect); - decoderThread.start(); + if(decodeMode != DecodeMode.NONE && previewActive) { + decoderThread = new DecoderThread(cameraInstance, decoder, resultHandler); + decoderThread.setCropRect(previewFramingRect); + decoderThread.start(); + } } /** diff --git a/zxing-android/src/com/journeyapps/barcodescanner/RotationListener.java b/zxing-android/src/com/journeyapps/barcodescanner/RotationListener.java index 07277ef1..1a86fde2 100644 --- a/zxing-android/src/com/journeyapps/barcodescanner/RotationListener.java +++ b/zxing-android/src/com/journeyapps/barcodescanner/RotationListener.java @@ -7,6 +7,10 @@ import android.view.WindowManager; /** * Hack to detect when screen rotation is reversed, since that does not cause a configuration change. + * + * If it is changed through something other than the sensor (e.g. programmatically), this may not work. + * + * See http://stackoverflow.com/q/9909037 */ public abstract class RotationListener extends OrientationEventListener { private int lastRotation; |
