У Surface не было действительного родного Surface для Camera2

Я интегрировал camera2 с textureView. Он работает на всех устройствах, но на планшете, когда мы делаем снимок в первый раз, происходит сбой и отображаются следующие журналы.

 Fatal Exception: java.lang.IllegalArgumentException: Surface had no valid native Surface.
           at android.hardware.camera2.legacy.LegacyCameraDevice.nativeGetSurfaceId(LegacyCameraDevice.java)
           at android.hardware.camera2.legacy.LegacyCameraDevice.getSurfaceId(LegacyCameraDevice.java:658)
           at android.hardware.camera2.legacy.LegacyCameraDevice.containsSurfaceId(LegacyCameraDevice.java:678)
           at android.hardware.camera2.legacy.RequestThreadManager$2.onPictureTaken(RequestThreadManager.java:220)
           at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1248)
           at android.os.Handler.dispatchMessage(Handler.java:111)
           at android.os.Looper.loop(Looper.java:207)
           at android.hardware.camera2.legacy.CameraDeviceUserShim$CameraLooper.run(CameraDeviceUserShim.java:136)
           at java.lang.Thread.run(Thread.java:818)

Следующий код используется для захвата изображения.

 protected void takePicture() {
        if (getContext() == null || cameraDevice == null) return;

        lockFocus();
        CameraManager manager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
        try {
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
            if (characteristics != null) {
                sizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
            }

            ImageReader reader = getImageReader();
            if (reader == null) return;

            List<Surface> outputSurfaces = getSurfaces(reader);
            final CaptureRequest.Builder captureBuilder = getCaptureBuilder(reader);

            final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
                    super.onCaptureCompleted(session, request, result);
                }
            };
            cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(CameraCaptureSession session) {
                    try {
                        session.capture(captureBuilder.build(), captureListener, null);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(CameraCaptureSession session) {
                }
            }, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Любая помощь будет оценена по достоинству.


person Ragini    schedule 02.04.2018    source источник
comment
Возможный дубликат - stackoverflow.com/questions/39788777/   -  person Darshan Pania    schedule 02.04.2018
comment
@DarshanPania Это решение не работает.   -  person Ragini    schedule 02.04.2018
comment
Не могли бы вы добавить код к своему вопросу, чтобы помочь понять, что происходит, когда камера захватывает изображение и возвращается?   -  person Darshan Pania    schedule 02.04.2018
comment
@DarshanPania - я добавил код. пожалуйста, проверьте.   -  person Ragini    schedule 02.04.2018
comment
Что это за getSurfaces( ImageReader )? Это может вернуть что-то неправильное для устаревшей камеры2. Когда ваша камера CameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY, вам может быть проще снимать в формате JPEG с помощью устаревшего Camera API. На старых устройствах camera2 может иметь некоторые сбои, которые очень сложно устранить.   -  person Alex Cohn    schedule 02.04.2018


Ответы (1)


Это может произойти, если ImageReader собирает мусор до завершения захвата изображения с камеры.

Сохраняет ли метод getImageReader средство чтения изображений где-то постоянно (например, в качестве члена класса)? Если нет, поверхность из ImageReader похожа на слабую ссылку и не будет препятствовать ее удалению.

person Eddy Talvala    schedule 02.04.2018