我该如何纠正这个持续性错误?
我在没有摄像头的安卓系统上使用 OTG 摄像头。
我为 YUV_420_888 使用了最小分辨率 320x240。 第一次,有时第二次它有效,之后我不断收到错误消息: 相机设备遇到致命错误。摄像头设备需要重新打开才能再次使用。
在这个想法中,我打开相机和会话持续 15 秒(由处理程序),然后它自动关闭。 谢谢
我的 API(不是全部)
static public CaptureRequest.Builder preparePreviewCapture(@NonNull CameraDevice device, @NonNull List<Surface> surfaces) throws Exception {
try {
CaptureRequest.Builder requestBuilder = device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
ApiCompatHelper.foreach(surfaces, (surfaceIterator, integer, surface) -> {
requestBuilder.addTarget(surface);
return false;
});
return requestBuilder;
} catch (Exception e)
{
e.getStackTrace();
throw new Exception(e.getCause());
}
}
static public void createCaptureSession(@NonNull CameraDevice device, @NonNull CameraCaptureSession.StateCallback callback, @NonNull List<Surface> surfaces) throws SecurityException, Exception {
device.createCaptureSession(surfaces, callback, mBackgroundHandler /*null*/);
}
static public void repeatRequest(@NonNull CameraCaptureSession session, @NonNull CaptureRequest.Builder builder, @Nullable CameraCaptureSession.CaptureCallback captureCallback) throws CameraAccessException {
//builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
session.setRepeatingRequest(builder.build(), captureCallback, mBackgroundHandler);
}
public static void openCamera(final String cameraId, CameraStateCallback callback) throws ExceptionInInitializerError, CameraAccessException, SecurityException {
if (mBackgroundHandler == null) throw new ExceptionInInitializerError("You must execute startBackgroundThread() in first");
mManager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onClosed(@NonNull CameraDevice camera) {
LogHelper.debugFunction(false);
super.onClosed(camera);
callback.onClosed(camera);
}
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
LogHelper.debugFunction(false);
callback.onOpened(cameraDevice);
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
LogHelper.debugFunction(false);
callback.onDisconnected(cameraDevice);
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int error) {
LogHelper.debugFunction(false);
callback.onError(cameraDevice, error);
}
}, mBackgroundHandler);
}
打开和关闭
private void openCamera() {
if (!CameraApi2Utils.checkPermissionsGranted(this)) {
CameraApi2Utils.requestPermissions(this);
return;
}
String id = "0";
try {
if (mCameraDevice == null) {
CameraApi2Utils.openCamera(id, this);
} else {
//
}
} catch (Exception e) {
e.printStackTrace();
closeCamera(true);
}
}
private void closeCamera(boolean initvar) {
SafeUtils.execSafe(() -> mTaskHandler,false,(t)-> {
t.removeCallbacks(mStopCameraRunnable);
});
if (initvar)
{
}
mCameraCaptureSessions = null;
SafeUtils.execSafe(()->mCameraDevice,false,(d)->d.close());
mCameraDevice = null;
SafeUtils.execSafe(()->mPreviewImageReader,false,(i)-> i.close());
mPreviewImageReader = null;
}
会话和图像阅读器
protected void prepareInternalPreviewCapture() throws Exception {
if (mPreviewImageReader == null) {
mPreviewImageReader = CameraApi2Utils.prepareInternalCapture(mLowResolution, ImageFormat.YUV_420_888, 2, reader -> {
if (RendererHelper.calculFps(fps)) {
LogHelper.debug("fps: %d - %dx%d", fps[2], reader.getWidth(), reader.getHeight());
}
try (Image image = reader.acquireLatestImage()) {
if (image != null) {
boolean preview = DataVolatileHelper.get("preview", false);
if (preview) {
byte[] imageBytes = GraphicHelper.NV21toJPEG(
GraphicHelper.YUV_420_888toNV21(image),
image.getWidth(), image.getHeight(), 20);
SafeUtils.execSafe(() -> BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length), false, (b) -> {
if (mPreviewHandler != null)
mPreviewHandler.post(new PreviewRunnable(b, 0));
}, (b) -> b.recycle(), null);
}
}
}
});
}
}
protected void createCameraPreviewSession() {
try {
prepareInternalPreviewCapture();
Surface surface = mPreviewImageReader.getSurface();
mPreviewBuilder = CameraApi2Utils.preparePreviewCapture(mCameraDevice, surface);
CameraApi2Utils.createCaptureSession(mCameraDevice, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
if (mTaskHandler != null) {
mTaskHandler.removeCallbacks(mStopCameraRunnable);
mTaskHandler.postDelayed(mStopCameraRunnable, 15000);
}
if (mCameraDevice == null) {
LogHelper.debug("mCameraDevice == null");
closeCamera(true);
return;
}
// When the session is ready, we start displaying the preview.
mCameraCaptureSessions = session;
mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
CameraApi2Utils.repeatRequest(mCameraCaptureSessions, mPreviewBuilder, (CameraCaptureSession.CaptureCallback) null);
} catch (Exception e) {
e.printStackTrace();
closeCamera(true);
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
closeCamera(true);
}
}, surface);
} catch (Exception e) {
e.printStackTrace();
closeCamera(true);
}
}
活动
@Override
public void onOpened(@NonNull CameraDevice camera) {
mCameraDevice = camera;
//SafeUtils.set("camera", camera);
//SafeUtils.releaseSafe("camera");
SafeUtils.execSafe(() -> mTaskHandler,false,(t)-> {
t.removeCallbacks(mStopCameraRunnable);
t.postDelayed(mStopCameraRunnable, 20000);
});
createCameraPreviewSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
closeCamera(true);
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
LogHelper.error(CameraApi2Utils.getErrorDescription(error));
if (error == CameraDevice.StateCallback.ERROR_CAMERA_DEVICE )
{
closeCamera(false);
SafeUtils.execSafe(()->mTaskHandler,false,(t)-> t.postDelayed(()->openCamera(), 2000));
} else
closeCamera(true);
}
@Override
public void onClosed(@NonNull CameraDevice camera) {
}
Runnable mStopCameraRunnable = new Runnable() {
@Override
public void run() {
SafeUtils.execSafe(()->mTaskHandler,false, (t)->t.removeCallbacks(mStopCameraRunnable));
closeCamera(true);
}
};