Ragini
Ragini

Reputation: 775

Surface had no valid native Surface for Camera2

I've integrated camera2 with textureVIew. It works on all devices but on tablet when we capture image for first time, it crashesand displays following logs.

 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)

Following code is used to capture the image.

 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();
        }
    }

Any help would be appreciated.

Upvotes: 1

Views: 1273

Answers (1)

Eddy Talvala
Eddy Talvala

Reputation: 18097

That can happen if the ImageReader gets garbage collected before the camera picture capture completes.

Does the getImageReader method store the image reader somewhere permanent (like as a class member)? If not, the Surface from the ImageReader is like a weak reference, and will not keep it from being removed.

Upvotes: 1

Related Questions