Android: camera2 在 capture() 中崩溃

Android: camera2 crash in capture()

我最近开始学习如何使用Android camera2,但是当我想拍照时它会崩溃。 我只知道它崩溃的地方,但我不知道为什么。有人帮我找到问题吗?谢谢。

public void takePicture(){
    if(cameraDevice == null){
        return ;
    }
    try {
        ImageReader imageReader = ImageReader.newInstance(600, 800, ImageFormat.JPEG, 1);
        Surface imageReaderSurface = imageReader.getSurface();
        imageReader.setOnImageAvailableListener(new OnImageAvailableListener(), null);


        picturesRequestBuilder = cameraDevice.createCaptureRequest(cameraDevice.TEMPLATE_STILL_CAPTURE);
        // 将imageReader的surface作为CaptureRequest.Builder的目标
        picturesRequestBuilder.addTarget(imageReaderSurface);
        // 自动对焦
        CaptureRequest captureRequest = picturesRequestBuilder.build();
     /*   ArrayList<CaptureRequest> captureRequests = new ArrayList<>();
        for(int i=0;i<10;i++){
            captureRequests.add(captureRequest);
        }*/
        mCameraCaptureSession.capture(captureRequest, new CaptureCallback(),null);
        // mCameraCaptureSession.captureBurst(captureRequests, new CaptureCallback(),null);
    }
    catch (CameraAccessException e) {
        e.printStackTrace();
    }

}

我的错误日志。

2020-07-20 14:50:23.506 21999-21999/com.example.mycamera E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mycamera, PID: 21999
java.lang.IllegalStateException: Could not execute method for android:onClick
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:402)
    at android.view.View.performClick(View.java:7448)
    at android.view.View.performClickInternal(View.java:7425)
    at android.view.View.access00(View.java:810)
    at android.view.View$PerformClick.run(View.java:28296)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
 Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:397)
    at android.view.View.performClick(View.java:7448) 
    at android.view.View.performClickInternal(View.java:7425) 
    at android.view.View.access00(View.java:810) 
    at android.view.View$PerformClick.run(View.java:28296) 
    at android.os.Handler.handleCallback(Handler.java:938) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:223) 
    at android.app.ActivityThread.main(ActivityThread.java:7656) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
 Caused by: java.lang.IllegalArgumentException: CaptureRequest contains unconfigured Input/Output Surface!
    at android.hardware.camera2.CaptureRequest.convertSurfaceToStreamId(CaptureRequest.java:738)
    at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:1191)
    at android.hardware.camera2.impl.CameraDeviceImpl.capture(CameraDeviceImpl.java:1051)
    at android.hardware.camera2.impl.CameraCaptureSessionImpl.capture(CameraCaptureSessionImpl.java:188)
    at com.example.mycamera.MainActivity.takePicture(MainActivity.java:267)
    at com.example.mycamera.MainActivity.button(MainActivity.java:69)
    at java.lang.reflect.Method.invoke(Native Method) 
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:397) 
    at android.view.View.performClick(View.java:7448) 
    at android.view.View.performClickInternal(View.java:7425) 
    at android.view.View.access00(View.java:810) 
    at android.view.View$PerformClick.run(View.java:28296) 
    at android.os.Handler.handleCallback(Handler.java:938) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:223) 
    at android.app.ActivityThread.main(ActivityThread.java:7656) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

2020-07-20 14:50:23.693 21999-21999/? I/Process:发送信号。 PID:21999 SIG:9

您不能在 CaptureRequest 中添加不属于提供给 createCaptureSession 的 Surface 的 Surface。在您的代码中,只有在您想要拍照时才创建一个 ImageReader,而 API 告诉您这是无效的:

Caused by: java.lang.IllegalArgumentException: CaptureRequest contains unconfigured Input/Output Surface!

因此,要么在设置捕获会话的同时设置 ImageReader 并将其 Surface 包含在输出目标列表中,要么在包含新创建的 ImageReader 的 takePicture 中创建一个新的捕获会话。

不推荐后者,因为创建新的捕获会话会短暂暂停预览。因此,在调用 CameraDevice.createCaptureSession 的位置创建 ImageReader,并确保将 ImageReader 作为封闭的一部分 class 以避免它被垃圾收集。