diff --git a/README.md b/README.md index 2e5f1461..58c442b5 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ compile 'com.otaliastudios:cameraview:1.1.1' - Plug in location tags with `setLocation()` API - `CameraUtils` to help with Bitmaps and orientations - Lightweight, no dependencies, just support `ExifInterface` +- Works down to API level 15 # Docs @@ -151,14 +152,12 @@ camera.addCameraListener(new CameraListener() { @Override public void onCameraOpened(CameraOptions options) {} - /** * Notifies that the camera session was closed. */ @Override public void onCameraClosed() {} - /** * Notifies that a picture previously captured with capturePicture() * or captureSnapshot() is ready to be shown or saved. @@ -169,14 +168,20 @@ camera.addCameraListener(new CameraListener() { @Override public void onPictureTaken(byte[] picture) {} - /** * Notifies that a video capture has just ended. The file parameter is the one that * was passed to startCapturingVideo(File), or a fallback video file. */ @Override public void onVideoTaken(File video) {} - + + /** + * Notifies that the device was tilted or the window offset changed. + * The orientation passed can be used to align views (e.g. buttons) to the current + * camera viewport so they will appear correctly oriented to the user. + */ + @Override + public void onOrientationChanged(int orientation) /** * Notifies that user interacted with the screen and started focus with a gesture, @@ -186,7 +191,6 @@ camera.addCameraListener(new CameraListener() { @Override public void onFocusStart(PointF point) {} - /** * Notifies that a gesture focus event just ended, and the camera converged * to a new focus (and possibly exposure and white balance). @@ -194,7 +198,6 @@ camera.addCameraListener(new CameraListener() { @Override public void onFocusEnd(boolean successful, PointF point) {} - /** * Noitifies that a finger gesture just caused the camera zoom * to be changed. This can be used, for example, to draw a seek bar. @@ -202,7 +205,6 @@ camera.addCameraListener(new CameraListener() { @Override public void onZoomChanged(float newValue, float[] bounds, PointF[] fingers) {} - /** * Noitifies that a finger gesture just caused the camera exposure correction * to be changed. This can be used, for example, to draw a seek bar. diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraListener.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraListener.java index bbc76484..de521fd3 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraListener.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraListener.java @@ -1,6 +1,7 @@ package com.otaliastudios.cameraview; import android.graphics.PointF; +import android.support.annotation.UiThread; import java.io.File; @@ -13,6 +14,7 @@ public abstract class CameraListener { * * @param options camera supported options */ + @UiThread public void onCameraOpened(CameraOptions options) { } @@ -21,6 +23,7 @@ public abstract class CameraListener { /** * Notifies that the camera session was closed. */ + @UiThread public void onCameraClosed() { } @@ -35,6 +38,7 @@ public abstract class CameraListener { * * @param jpeg captured picture */ + @UiThread public void onPictureTaken(byte[] jpeg) { } @@ -50,11 +54,28 @@ public abstract class CameraListener { * * @param video file hosting the mp4 video */ + @UiThread public void onVideoTaken(File video) { } + /** + * Notifies that the device was tilted or the window offset changed. + * The orientation passed is exactly the rotation that a View should have, + * in order to appear correctly oriented to the user, considering the way she is + * holding the device, and the native activity orientation. + * + * This is meant to be used for aligning views (e.g. buttons) to the current camera viewport. + * + * @param orientation either 0, 90, 180 or 270 + */ + @UiThread + public void onOrientationChanged(int orientation) { + + } + + /** * Notifies that user interacted with the screen and started focus with a gesture, * and the autofocus is trying to focus around that area. @@ -62,6 +83,7 @@ public abstract class CameraListener { * * @param point coordinates with respect to CameraView.getWidth() and CameraView.getHeight() */ + @UiThread public void onFocusStart(PointF point) { } @@ -75,6 +97,7 @@ public abstract class CameraListener { * @param successful whether camera succeeded * @param point coordinates with respect to CameraView.getWidth() and CameraView.getHeight() */ + @UiThread public void onFocusEnd(boolean successful, PointF point) { } @@ -88,6 +111,7 @@ public abstract class CameraListener { * @param bounds min and max bounds for newValue (fixed to 0 ... 1) * @param fingers finger positions that caused the event */ + @UiThread public void onZoomChanged(float newValue, float[] bounds, PointF[] fingers) { } @@ -101,6 +125,7 @@ public abstract class CameraListener { * @param bounds min and max bounds for newValue, as returned by {@link CameraOptions} * @param fingers finger positions that caused the event */ + @UiThread public void onExposureCorrectionChanged(float newValue, float[] bounds, PointF[] fingers) { } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 4bd9714d..35775897 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -140,16 +140,31 @@ public class CameraView extends FrameLayout { if (!isInEditMode()) { mOrientationHelper = new OrientationHelper(context) { + + private Integer mDisplayOffset; + private Integer mDeviceOrientation; + @Override public void onDisplayOffsetChanged(int displayOffset) { mCameraController.onDisplayOffset(displayOffset); mPreviewImpl.onDisplayOffset(displayOffset); + mDisplayOffset = displayOffset; + send(); } @Override protected void onDeviceOrientationChanged(int deviceOrientation) { mCameraController.onDeviceOrientation(deviceOrientation); mPreviewImpl.onDeviceOrientation(deviceOrientation); + mDeviceOrientation = deviceOrientation; + send(); + } + + private void send() { + if (mDeviceOrientation == null) return; + if (mDisplayOffset == null) return; + int value = (mDeviceOrientation + mDisplayOffset) % 360; + mCameraCallbacks.dispatchOnOrientationChanged(value); } }; } @@ -1286,6 +1301,18 @@ public class CameraView extends FrameLayout { } + public void dispatchOnOrientationChanged(final int value) { + uiHandler.post(new Runnable() { + @Override + public void run() { + for (CameraListener listener : mListeners) { + listener.onOrientationChanged(value); + } + } + }); + } + + public void dispatchOnZoomChanged(final float newValue, final PointF[] fingers) { uiHandler.post(new Runnable() { @Override