I created a custom surface view for camera, to take a picture when button is clicked but it always reset to onCaptureFailed
Here is my full code https://codeshare.io/VZAAm3
public void captureImage() {
// Capture an image when the custom button is clicked
if (cameraDevice != null) {
try {
int width = previewSize.getWidth();
int height = previewSize.getHeight();
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraDevice.getId());
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if(map != null) {
Size[] outputSizes = map.getOutputSizes(ImageFormat.JPEG);
if (outputSizes != null && outputSizes.length > 0) {
width = outputSizes[0].getWidth();
height = outputSizes[0].getHeight();
}
}
try (ImageReader cameraImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1)) {
List<Surface> outputSurface = new ArrayList<>(2);
outputSurface.add(cameraImageReader.getSurface());
outputSurface.add(new Surface(cameraPreview.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(cameraImageReader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
//Check orientation base on device
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
cameraImageReader.setOnImageAvailableListener(imageReaderListener, null);
Log.e("Capture", "Captured");
}
@Override
public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
int reason = failure.getReason();
int sequenceId = failure.getSequenceId();
Log.e("Capture", "Capture failed with reason: " + reason + ", sequenceId: " + sequenceId);
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
}
}, null);
} catch (CameraAccessException e) {
// Handle camera access exception
}
} catch (CameraAccessException e) {
// Handle camera access exception
}
}
}