Я немного боролся с Android Camera2 API. Когда я поворачиваю свое устройство, я получаю
android.hardware.camera2.CameraAccessException: CAMERA_DISCONNECTED (2): checkPidStatus:1795: The camera device has been disconnected
Во время отладки я обнаружил, что это происходит в этой части кода
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
, и затем переходит к разделу catch, который обрабатывает исключение CameraAccessException. Иногда фон становится белым, и я не вижу предварительный просмотр камеры. Вот часть кода:
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull final CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
mCameraDevice = cameraDevice;
createCameraPreviewSession();
}
@Override
public void onDisconnected(@NonNull final CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
@Override
public void onError(@NonNull final CameraDevice cameraDevice, final int error) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
final Activity activity = getActivity();
if (null != activity) {
activity.finish();
}
}
};
private void createCameraPreviewSession() {
try {
final SurfaceTexture texture = mAutoFitTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
final Surface surface = new Surface(texture);
mPreviewRequestBuilder
= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mCameraDevice.createCaptureSession(Arrays.asList(surface),
getStateCallback(), null
);
} catch (CameraAccessException e) {
e.printStackTrace();
Log.e("CameraAccessException: createCameraPreviewSession()", e.toString());
}
}
@NonNull
private CameraCaptureSession.StateCallback getStateCallback() {
return new CameraCaptureSession.StateCallback() {
@Override
public void onReady(@NonNull CameraCaptureSession session) {
super.onReady(session);
Log.d("getStateCallback: onReady()", "");
}
@Override
public void onClosed(@NonNull CameraCaptureSession session) {
super.onClosed(session);
Log.d("getStateCallback: onClosed()", "");
}
@Override
public void onConfigured(@NonNull final CameraCaptureSession cameraCaptureSession) {
if (null == mCameraDevice) {
return;
}
mCaptureSession = cameraCaptureSession;
try {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, mBackgroundHandler);
} catch (final CameraAccessException e) {
e.printStackTrace();
Log.e("CameraAccessException: onConfigured()", e.toString());
}
}
@Override
public void onConfigureFailed(
@NonNull final CameraCaptureSession cameraCaptureSession) {
Log.d("getStateCallback: onConfigureFailed()", "failed");
showToast();
}
};
}
private void openCamera(final int width, final int height) {
if (ContextCompat.checkSelfPermission(Objects.requireNonNull(getActivity()), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestCameraPermission();
return;
}
setUpCameraOutputs(width, height);
configureTransform(width, height);
final CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
try {
Objects.requireNonNull(manager).openCamera(mCameraId, mStateCallback, mBackgroundHandler);
} catch (final CameraAccessException e) {
e.printStackTrace();
Log.e("CameraAccessException: openCamera()", e.toString());
}
initAROverlayView();
}
@MainThread
private void closeCamera() {
try {
try {
mCameraOpenCloseLock.acquire();
} catch (InterruptedException e) {
Log.e("InterruptedException", e.toString());
}
if (null != mCaptureSession) {
mCaptureSession.close();
mCaptureSession = null;
}
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
} finally {
mCameraOpenCloseLock.release();
}
}
@Override
public void onResume() {
super.onResume();
startBackgroundThread();
registerSensors();
if (mAutoFitTextureView.isAvailable()) {
openCamera(mAutoFitTextureView.getWidth(), mAutoFitTextureView.getHeight());
} else {
mAutoFitTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
}
@Override
public void onPause() {
try {
closeCamera();
stopBackgroundThread();
} catch (InterruptedException e) {
Log.e("InterruptedException", e.toString());
}
super.onPause();
}