From 25bfa6126e06fb1b3a40ebf1a525dd2e537905b2 Mon Sep 17 00:00:00 2001 From: Michael Specht <15450970+michaelspecht@users.noreply.github.com> Date: Tue, 5 Jan 2021 16:13:26 -0500 Subject: [PATCH] add try catch to catch exceptions when takePicture fails, to give the user a better experience than an app crash --- .../otaliastudios/cameraview/CameraUtils.java | 2 +- .../picture/Full1PictureRecorder.java | 104 ++++++++++-------- .../picture/Full2PictureRecorder.java | 21 +++- 3 files changed, 75 insertions(+), 52 deletions(-) diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java index 17e06cf2..fdb8593e 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java @@ -157,7 +157,7 @@ public class CameraUtils { @NonNull final BitmapCallback callback) { decodeBitmap(source, Integer.MAX_VALUE, Integer.MAX_VALUE, callback); } - + /** * Decodes an input byte array and outputs a Bitmap that is ready to be displayed. * The difference with {@link android.graphics.BitmapFactory#decodeByteArray(byte[], int, int)} diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java index 0d099e78..84d7cf8d 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java @@ -1,10 +1,12 @@ package com.otaliastudios.cameraview.picture; import android.hardware.Camera; +import android.util.Log; import androidx.annotation.NonNull; import androidx.exifinterface.media.ExifInterface; +import com.otaliastudios.cameraview.CameraException; import com.otaliastudios.cameraview.PictureResult; import com.otaliastudios.cameraview.engine.Camera1Engine; import com.otaliastudios.cameraview.engine.offset.Reference; @@ -44,57 +46,67 @@ public class Full1PictureRecorder extends FullPictureRecorder { // or takePicture can hang and leave the camera in a bad state. mCamera.setPreviewCallbackWithBuffer(null); mEngine.getFrameManager().release(); - mCamera.takePicture( - new Camera.ShutterCallback() { - @Override - public void onShutter() { - LOG.i("take(): got onShutter callback."); - dispatchOnShutter(true); - } - }, - null, - null, - new Camera.PictureCallback() { - @Override - public void onPictureTaken(byte[] data, final Camera camera) { - LOG.i("take(): got picture callback."); - int exifRotation; - try { - ExifInterface exif = new ExifInterface(new ByteArrayInputStream(data)); - int exifOrientation = exif.getAttributeInt( - ExifInterface.TAG_ORIENTATION, - ExifInterface.ORIENTATION_NORMAL); - exifRotation = ExifHelper.getOrientation(exifOrientation); - } catch (IOException e) { - exifRotation = 0; + try { + mCamera.takePicture( + new Camera.ShutterCallback() { + @Override + public void onShutter() { + LOG.i("take(): got onShutter callback."); + dispatchOnShutter(true); } - mResult.data = data; - mResult.rotation = exifRotation; - LOG.i("take(): starting preview again. ", Thread.currentThread()); + }, + null, + null, + new Camera.PictureCallback() { + @Override + public void onPictureTaken(byte[] data, final Camera camera) { + LOG.i("take(): got picture callback."); + int exifRotation; + try { + ExifInterface exif = new ExifInterface(new ByteArrayInputStream(data)); + int exifOrientation = exif.getAttributeInt( + ExifInterface.TAG_ORIENTATION, + ExifInterface.ORIENTATION_NORMAL); + exifRotation = ExifHelper.getOrientation(exifOrientation); + } catch (IOException e) { + exifRotation = 0; + } + mResult.data = data; + mResult.rotation = exifRotation; + LOG.i("take(): starting preview again. ", Thread.currentThread()); - // It's possible that by the time this callback is invoked, we're not previewing - // anymore, so check before restarting preview. - if (mEngine.getState().isAtLeast(CameraState.PREVIEW)) { - camera.setPreviewCallbackWithBuffer(mEngine); - Size previewStreamSize = mEngine.getPreviewStreamSize(Reference.SENSOR); - if (previewStreamSize == null) { - throw new IllegalStateException("Preview stream size " + - "should never be null here."); + // It's possible that by the time this callback is invoked, we're not previewing + // anymore, so check before restarting preview. + if (mEngine.getState().isAtLeast(CameraState.PREVIEW)) { + camera.setPreviewCallbackWithBuffer(mEngine); + Size previewStreamSize = mEngine.getPreviewStreamSize(Reference.SENSOR); + if (previewStreamSize == null) { + throw new IllegalStateException("Preview stream size " + + "should never be null here."); + } + // Need to re-setup the frame manager, otherwise no frames are processed + // after takePicture() is called + mEngine.getFrameManager().setUp( + mEngine.getFrameProcessingFormat(), + previewStreamSize, + mEngine.getAngles() + ); + camera.startPreview(); } - // Need to re-setup the frame manager, otherwise no frames are processed - // after takePicture() is called - mEngine.getFrameManager().setUp( - mEngine.getFrameProcessingFormat(), - previewStreamSize, - mEngine.getAngles() - ); - camera.startPreview(); + dispatchResult(); } - dispatchResult(); } - } - ); - LOG.i("take() returned."); + ); + LOG.i("take() returned."); + } catch (Exception e) { + String msg = "Error"; + if (e.getMessage() != null) { + msg = e.getMessage(); + } + Log.e("onTakePicture:", msg); + mError = e; + dispatchResult(); + } } @Override diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full2PictureRecorder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full2PictureRecorder.java index 10ea5775..be5a20e6 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full2PictureRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full2PictureRecorder.java @@ -8,6 +8,7 @@ import android.hardware.camera2.TotalCaptureResult; import android.media.Image; import android.media.ImageReader; import android.os.Build; +import android.util.Log; import com.otaliastudios.cameraview.PictureResult; import com.otaliastudios.cameraview.controls.PictureFormat; @@ -87,12 +88,22 @@ public class Full2PictureRecorder extends FullPictureRecorder @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { super.onCaptureCompleted(holder, request, result); - if (mResult.format == PictureFormat.DNG) { - mDngCreator = new DngCreator(holder.getCharacteristics(this), result); - mDngCreator.setOrientation(ExifHelper.getExifOrientation(mResult.rotation)); - if (mResult.location != null) { - mDngCreator.setLocation(mResult.location); + try { + if (mResult.format == PictureFormat.DNG) { + mDngCreator = new DngCreator(holder.getCharacteristics(this), result); + mDngCreator.setOrientation(ExifHelper.getExifOrientation(mResult.rotation)); + if (mResult.location != null) { + mDngCreator.setLocation(mResult.location); + } + } + } catch (Exception e) { + String msg = "Error"; + if (e.getMessage() != null) { + msg = e.getMessage(); } + Log.e("onCaptureCompleted:", msg); + mError = e; + dispatchResult(); } } };