From d2d6978a3c604cd8edd07f74944510108e34cf93 Mon Sep 17 00:00:00 2001 From: Tim H Date: Sat, 11 Nov 2017 17:21:35 +0100 Subject: [PATCH] fetch errors that prevent the camera from being initialized in the first place --- README.md | 23 +++ .../otaliastudios/cameraview/CameraView.java | 158 ++++++++++-------- 2 files changed, 115 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 60b9c5f4..88907a71 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,29 @@ camera.addCameraListener(new CameraListener() { }); ``` + +Some rare exceptions can occur during initialization of the camera. This prevents any further camera + usage and occurs before you can attach your custom error handler. +So you should additionally wrap the camera initialization in a try-catch-block: +```java +try { + cameraView = new CameraView(context); +} +catch (CameraException e) { + // camera is (temporary) unavailable +} +``` + +Or if you created the CameraView by adding it to your XML layout: +```java +try { + inflater.inflate(R.layout.camera, mainContainer, false); +} +catch (CameraException e) { + // camera is (temporary) unavailable +} +``` + #### Advanced Custom Handler Furthermore, you can distinguish different error types. E.g. some of them imply that the CameraView should be disabled or restarted while others may be ignored in some use cases. diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 6a7a7cfb..fa1efa54 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -75,11 +75,22 @@ public class CameraView extends FrameLayout { private Handler mUiHandler; private WorkerHandler mWorkerHandler; + /** + * + * @param context + * @throws CameraUnavailableException if the initialization failed for any (camera-related) reason. + */ public CameraView(@NonNull Context context) { super(context, null); init(context, null); } + /** + * + * @param context + * @param attrs + * @throws CameraUnavailableException if the initialization failed for any (camera-related) reason. + */ public CameraView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context, attrs); @@ -87,74 +98,89 @@ public class CameraView extends FrameLayout { //region Init + /** + * + * @param context + * @param attrs + * @throws CameraUnavailableException if the initialization failed for any (camera-related) reason. + */ @SuppressWarnings("WrongConstant") private void init(@NonNull Context context, @Nullable AttributeSet attrs) { - setWillNotDraw(false); - TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CameraView, 0, 0); - // Self managed - int jpegQuality = a.getInteger(R.styleable.CameraView_cameraJpegQuality, DEFAULT_JPEG_QUALITY); - boolean cropOutput = a.getBoolean(R.styleable.CameraView_cameraCropOutput, DEFAULT_CROP_OUTPUT); - boolean playSounds = a.getBoolean(R.styleable.CameraView_cameraPlaySounds, DEFAULT_PLAY_SOUNDS); - - // Camera controller params - Facing facing = Facing.fromValue(a.getInteger(R.styleable.CameraView_cameraFacing, Facing.DEFAULT.value())); - Flash flash = Flash.fromValue(a.getInteger(R.styleable.CameraView_cameraFlash, Flash.DEFAULT.value())); - Grid grid = Grid.fromValue(a.getInteger(R.styleable.CameraView_cameraGrid, Grid.DEFAULT.value())); - WhiteBalance whiteBalance = WhiteBalance.fromValue(a.getInteger(R.styleable.CameraView_cameraWhiteBalance, WhiteBalance.DEFAULT.value())); - VideoQuality videoQuality = VideoQuality.fromValue(a.getInteger(R.styleable.CameraView_cameraVideoQuality, VideoQuality.DEFAULT.value())); - SessionType sessionType = SessionType.fromValue(a.getInteger(R.styleable.CameraView_cameraSessionType, SessionType.DEFAULT.value())); - Hdr hdr = Hdr.fromValue(a.getInteger(R.styleable.CameraView_cameraHdr, Hdr.DEFAULT.value())); - Audio audio = Audio.fromValue(a.getInteger(R.styleable.CameraView_cameraAudio, Audio.DEFAULT.value())); - - // Gestures - GestureAction tapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureTap, GestureAction.DEFAULT_TAP.value())); - GestureAction longTapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureLongTap, GestureAction.DEFAULT_LONG_TAP.value())); - GestureAction pinchGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGesturePinch, GestureAction.DEFAULT_PINCH.value())); - GestureAction scrollHorizontalGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureScrollHorizontal, GestureAction.DEFAULT_SCROLL_HORIZONTAL.value())); - GestureAction scrollVerticalGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureScrollVertical, GestureAction.DEFAULT_SCROLL_VERTICAL.value())); - a.recycle(); - - // Components - mCameraCallbacks = new Callbacks(); - mCameraController = instantiateCameraController(mCameraCallbacks); - mUiHandler = new Handler(Looper.getMainLooper()); - mWorkerHandler = WorkerHandler.get("CameraViewWorker"); - - // Views - mGridLinesLayout = new GridLinesLayout(context); - mPinchGestureLayout = new PinchGestureLayout(context); - mTapGestureLayout = new TapGestureLayout(context); - mScrollGestureLayout = new ScrollGestureLayout(context); - addView(mGridLinesLayout); - addView(mPinchGestureLayout); - addView(mTapGestureLayout); - addView(mScrollGestureLayout); - - // Apply self managed - setCropOutput(cropOutput); - setJpegQuality(jpegQuality); - setPlaySounds(playSounds); - - // Apply camera controller params - setFacing(facing); - setFlash(flash); - setSessionType(sessionType); - setVideoQuality(videoQuality); - setWhiteBalance(whiteBalance); - setGrid(grid); - setHdr(hdr); - setAudio(audio); - - // Apply gestures - mapGesture(Gesture.TAP, tapGesture); - // mapGesture(Gesture.DOUBLE_TAP, doubleTapGesture); - mapGesture(Gesture.LONG_TAP, longTapGesture); - mapGesture(Gesture.PINCH, pinchGesture); - mapGesture(Gesture.SCROLL_HORIZONTAL, scrollHorizontalGesture); - mapGesture(Gesture.SCROLL_VERTICAL, scrollVerticalGesture); - - if (!isInEditMode()) { - mOrientationHelper = new OrientationHelper(context, mCameraCallbacks); + try { + setWillNotDraw(false); + TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CameraView, 0, 0); + // Self managed + int jpegQuality = a.getInteger(R.styleable.CameraView_cameraJpegQuality, DEFAULT_JPEG_QUALITY); + boolean cropOutput = a.getBoolean(R.styleable.CameraView_cameraCropOutput, DEFAULT_CROP_OUTPUT); + boolean playSounds = a.getBoolean(R.styleable.CameraView_cameraPlaySounds, DEFAULT_PLAY_SOUNDS); + + // Camera controller params + Facing facing = Facing.fromValue(a.getInteger(R.styleable.CameraView_cameraFacing, Facing.DEFAULT.value())); + Flash flash = Flash.fromValue(a.getInteger(R.styleable.CameraView_cameraFlash, Flash.DEFAULT.value())); + Grid grid = Grid.fromValue(a.getInteger(R.styleable.CameraView_cameraGrid, Grid.DEFAULT.value())); + WhiteBalance whiteBalance = WhiteBalance.fromValue(a.getInteger(R.styleable.CameraView_cameraWhiteBalance, WhiteBalance.DEFAULT.value())); + VideoQuality videoQuality = VideoQuality.fromValue(a.getInteger(R.styleable.CameraView_cameraVideoQuality, VideoQuality.DEFAULT.value())); + SessionType sessionType = SessionType.fromValue(a.getInteger(R.styleable.CameraView_cameraSessionType, SessionType.DEFAULT.value())); + Hdr hdr = Hdr.fromValue(a.getInteger(R.styleable.CameraView_cameraHdr, Hdr.DEFAULT.value())); + Audio audio = Audio.fromValue(a.getInteger(R.styleable.CameraView_cameraAudio, Audio.DEFAULT.value())); + + // Gestures + GestureAction tapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureTap, GestureAction.DEFAULT_TAP.value())); + GestureAction longTapGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureLongTap, GestureAction.DEFAULT_LONG_TAP.value())); + GestureAction pinchGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGesturePinch, GestureAction.DEFAULT_PINCH.value())); + GestureAction scrollHorizontalGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureScrollHorizontal, GestureAction.DEFAULT_SCROLL_HORIZONTAL.value())); + GestureAction scrollVerticalGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureScrollVertical, GestureAction.DEFAULT_SCROLL_VERTICAL.value())); + a.recycle(); + + // Components + mCameraCallbacks = new Callbacks(); + mCameraController = instantiateCameraController(mCameraCallbacks); + mUiHandler = new Handler(Looper.getMainLooper()); + mWorkerHandler = WorkerHandler.get("CameraViewWorker"); + + // Views + mGridLinesLayout = new GridLinesLayout(context); + mPinchGestureLayout = new PinchGestureLayout(context); + mTapGestureLayout = new TapGestureLayout(context); + mScrollGestureLayout = new ScrollGestureLayout(context); + addView(mGridLinesLayout); + addView(mPinchGestureLayout); + addView(mTapGestureLayout); + addView(mScrollGestureLayout); + + // Apply self managed + setCropOutput(cropOutput); + setJpegQuality(jpegQuality); + setPlaySounds(playSounds); + + // Apply camera controller params + setFacing(facing); + setFlash(flash); + setSessionType(sessionType); + setVideoQuality(videoQuality); + setWhiteBalance(whiteBalance); + setGrid(grid); + setHdr(hdr); + setAudio(audio); + + // Apply gestures + mapGesture(Gesture.TAP, tapGesture); + // mapGesture(Gesture.DOUBLE_TAP, doubleTapGesture); + mapGesture(Gesture.LONG_TAP, longTapGesture); + mapGesture(Gesture.PINCH, pinchGesture); + mapGesture(Gesture.SCROLL_HORIZONTAL, scrollHorizontalGesture); + mapGesture(Gesture.SCROLL_VERTICAL, scrollVerticalGesture); + + if (!isInEditMode()) { + mOrientationHelper = new OrientationHelper(context, mCameraCallbacks); + } + } + catch (CameraException e) { + // Some rare exceptions can occur during the camera initialization. + // For instance, Camera.getCameraInfo() may fail for inevitable hardware reasons. + // If the initialization failed for any (camera-related) reason, the camera gets + // completely unavailable. + throw new CameraUnavailableException("Failed to initialize the camera.", e); } }