Camera2 android - 相机设备遇到致命错误摄像头设备需要重新打开才能再次使用

问题描述

我该如何纠正这个持续性错误?

我在没有摄像头的安卓系统上使用 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,(d)->d.close());
        mCameraDevice = null;

        SafeUtils.execSafe(()->mPreviewImageReader,(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,imageBytes.length),(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,(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,(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,(t)->t.removeCallbacks(mStopCameraRunnable));
        closeCamera(true);
    }
};

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)