add try catch to catch exceptions when takePicture fails (#1024)

* add try catch to catch exceptions when takePicture fails, to give the user a better experience than an app crash

* do not log errors, as they are alreayd logged by the camera engine, and do not put try catch around DNG captures

Co-authored-by: Mattia Iavarone <mat.iavarone@gmail.com>
pull/1030/head
Michael 4 years ago committed by GitHub
parent 0f6ab20c3e
commit 5d10277d7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraUtils.java
  2. 99
      cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full1PictureRecorder.java
  3. 9
      cameraview/src/main/java/com/otaliastudios/cameraview/picture/Full2PictureRecorder.java

@ -158,7 +158,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)}

@ -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,62 @@ 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) {
mError = e;
dispatchResult();
}
}
@Override

@ -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;
@ -86,7 +87,13 @@ public class Full2PictureRecorder extends FullPictureRecorder
public void onCaptureCompleted(@NonNull ActionHolder holder,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
super.onCaptureCompleted(holder, request, result);
try {
super.onCaptureCompleted(holder, request, result);
} catch (Exception e) {
mError = e;
dispatchResult();
}
if (mResult.format == PictureFormat.DNG) {
mDngCreator = new DngCreator(holder.getCharacteristics(this), result);
mDngCreator.setOrientation(ExifHelper.getExifOrientation(mResult.rotation));

Loading…
Cancel
Save