Java Android Camera2-当E/Camera错误变得不可用(即用户自拍)时,回调以拦截该错误

Java Android Camera2-当E/Camera错误变得不可用(即用户自拍)时,回调以拦截该错误,java,android,android-camera2,camera-api,Java,Android,Android Camera2,Camera Api,在我的应用程序中,我使用Camera2API在后台进行一些处理。我使用的是著名的Camera2Basic(尽管现在进行了大量修改)。一切都很好,但有一个明显的问题-当用户要求相机做一些事情(比如启动相机应用程序拍照)时,my Camera2退出,请查看日志: E/Camera: Error 2 I/RequestThread-1: Flushing all pending requests. I/RequestQueue: Repeating capture request cancelled.

在我的应用程序中,我使用Camera2API在后台进行一些处理。我使用的是著名的Camera2Basic(尽管现在进行了大量修改)。一切都很好,但有一个明显的问题-当用户要求相机做一些事情(比如启动相机应用程序拍照)时,my Camera2退出,请查看日志:

E/Camera: Error 2
I/RequestThread-1: Flushing all pending requests.
I/RequestQueue: Repeating capture request cancelled.
I/CameraDeviceState: Legacy camera service transitioning to state ERROR
E/RequestQueue: cancel failed: no repeating request exists for request id: 0
E/CameraDeviceState: Cannot receive result while in state: 0
W/CaptureCollector: previewProduced called with no preview request on queue!
W/MessageQueue: Handler (android.os.Handler) {32bb202} sending message to a Handler on a dead thread
                                                                  java.lang.IllegalStateException: Handler (android.os.Handler) {32bb202} sending message to a Handler on a dead thread
                                                                  ... (irrelevant) ...
                                                                      at android.os.Looper.loop(Looper.java:154)
                                                                      at android.os.HandlerThread.run(HandlerThread.java:61)
E/MyApp: disconnected
D/gralloc: gralloc_lock_ycbcr success. format : 11, usage: 3, ycbcr.y: 0x66903000, .cb: 0x66afd401, .cr: 0x66afd400, .ystride: 1920 , .cstride: 1920, .chroma_step: 2
E/BufferItemConsumer: [ImageReader-1920x1080f23m1-19683-0] Failed to release buffer: Unknown error -1 (1)
E/MyApp: closed
现在。。。在Camera1 API中,我能够在报告E/Camera错误2时准确截获并采取行动,使用以下方法:

mCamera.setErrorCallback(errorCallback);
但是在Camera2 API中,这种情况很有趣,因为即使我配置了StateCallback(请注意Log.e()对应于上面的LOGCAT输出),onError()根本不会触发,onClosed()和onDisconnected()触发太迟(!):

如果相机被用户的请求接管,为什么OneRor()不会触发?我怎样才能检测到这种情况?我认为,能够“利用”以下任何一个事件都可以做到这一点:

I/CameraDeviceState: Legacy camera service transitioning to state ERROR
E/RequestQueue: cancel failed: no repeating request exists for request id: 0
E/CameraDeviceState: Cannot receive result while in state: 0
感谢您的反馈。
M.

好的,进一步研究这个问题,我已经找到了一个解决方案。问题在于,本机支持Camera 1 API的“传统”设备虽然与Camera 2 API“协同工作”,但其行为与本机支持Camera 2 API的“有限”/“完整”设备不同

要检测设备类型,可以使用以下代码段:

CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
Integer deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); // 0 - limited, 1 - full, 2 - legacy, 3 - uber full
现在,“受限”和“完整”设备将按预期运行,当摄像头不可用时,StateCallback的onDisconnect()事件将触发,因此您可以做出反应。对于“遗留”设备,至少根据我的测试,这种情况发生得太晚了(根据原始问题中的LOGCAT)

解决方案似乎是根据硬件级别在摄像头API之间切换,然后使用
mCamera.setErrorCallback(errorCallback)
捕获摄像头1 API设备上的错误。像这样:

CameraErrorCallback errorCallback = new CameraErrorCallback();
@SuppressWarnings("deprecation")
public class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
    @Override
    public void onError(int error, android.hardware.Camera camera) {
    // Do something.
    }
}
CameraErrorCallback errorCallback = new CameraErrorCallback();
@SuppressWarnings("deprecation")
public class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
    @Override
    public void onError(int error, android.hardware.Camera camera) {
    // Do something.
    }
}