ImageReader.OnImageAvailableListener () не вызывается при съемке - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть приложение для камеры, разработанное для Android 26 SDK.Я счастливо использовал его с Motorola G5 и G6, но когда я перехожу на Motorola G7, приложение вылетает, когда я нажимаю кнопку, чтобы сделать снимок в моем приложении.

G7 работает под управлением Android 9. Iесть еще один телефон Android 9 Samsung S10 plus.S10 plus не падает, когда я нажимаю кнопку для съемки.

Во время отладки я заметил, что G7 не вызывает ImageReader.OnImageAvailableListener, в то время как S10 делает.Глядя на код, именно здесь изображение сохраняется для последующего использования в CameraCaptureSession.CaptureCallback.Обратный вызов ожидает, что байты будут заполнены, и вылетает, когда это не так (я не включил трассировку стека, потому что это не слишком бесполезно, но я могу, если вы думаете, что вы хотели бы видеть его).

Iможно заставить G7 сохранить изображение, если я буду «медленно» запускать его через «отладку» в некоторых случаях.

Так что у меня есть кнопка, которая вызывает функцию onImageCaptureClick (), внутри которой выполняется куча вещей, но один изон создает ImageReader.OnImageAvailableListener.OnImageAvailableListener сохраняет изображение и заполняет переменные байты из буфера изображения.Этот onImageAvailableListener присоединяется к моему считывателю с помощью reader.setOnImageAvailableListener (readerListener, null), и этот слушатель никогда не используется.Когда я вхожу в CaptureCallBack, байты переменной класса не заполняются, и приложение вылетает.

У вас есть идеи, где мне искать, чтобы решить эту проблему?

protected void onImageCaptureClick() {
    if (null == mCameraDevice) {
        logger.debug("null == mCameraDevice");
        Log.e(TAG, "cameraDevice is null");
        return;
    }
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

    try {
        CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraDevice.getId());
        Size[] jpegSizes = null;
        if (characteristics != null) {
            jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
        }
        int width = 640;
        int height = 480;
        if (jpegSizes != null && 0 < jpegSizes.length) {
            width = jpegSizes[0].getWidth();
            height = jpegSizes[0].getHeight();
        }
        ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
        List < Surface > outputSurfaces = new ArrayList < > (2);
        outputSurfaces.add(reader.getSurface());
        outputSurfaces.add(new Surface(mTextureView.getSurfaceTexture()));
        final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        captureBuilder.addTarget(reader.getSurface());

        if (mFlashMode == FLASH_MODE_OFF) {
            captureBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
            logger.debug("FLASH OFF");
        }

        if (mFlashMode == CONTROL_AE_MODE_ON) {
            captureBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                CaptureRequest.CONTROL_AE_MODE_ON);
            captureBuilder.set(CaptureRequest.FLASH_MODE,
                CaptureRequest.FLASH_MODE_TORCH);
            logger.debug("FLASH ON");
        }

        if (mFlashMode == CONTROL_AE_MODE_ON_AUTO_FLASH) {

            captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            captureBuilder.set(CaptureRequest.FLASH_MODE,
                CaptureRequest.FLASH_MODE_OFF);
            logger.debug("FLASH AUTO");
        }

        captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);

        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

        final File file = new File(_pictureUri.getPath());
        logger.debug("OnImageCaptureClick: _pictureUri is: " + _pictureUri.getPath());
        // ************************************
        // this listener is not used on the G7,
        // and so the image isn't saved.
        // ************************************
        ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {
                Image image = null;
                try {
                    image = reader.acquireLatestImage();
                    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                    bytes = new byte[buffer.capacity()];
                    buffer.get(bytes);
                    logger.debug("onImageCaptureClick, the filesize to save is: " + bytes.toString());
                    save();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (image != null) {
                        image.close();
                    }
                }
            }


            private void save() throws IOException {
                OutputStream output = null;
                try {
                    output = new FileOutputStream(file);
                    output.write(bytes);
                } finally {
                    if (null != output) {
                        output.close();
                    }
                }
            }


        };
        // ********************************************************
        // the reader sets the listener here but it is never called
        // and when I get in to the CaptureCallback the BitmapUtils
        // expects bytes to be populated and crashes the app
        // ********************************************************
        reader.setOnImageAvailableListener(readerListener, null);
        final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {

            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                super.onCaptureCompleted(session, request, result);

                try {
                    BitmapUtils.addTimeStampAndRotate(_pictureUri, bytes);


                    Intent intent = new Intent(CameraActivity.this, CameraReviewPhotoActivity.class);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, _pictureUri);
                    startActivityForResult(intent, CameraActivity.kRequest_Code_Approve_Image);

                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ImageReadException e) {
                    e.printStackTrace();
                } catch (ImageWriteException e) {
                    e.printStackTrace();
                }

            }
        };

        mCameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(CameraCaptureSession session) {
                try {
                    session.capture(captureBuilder.build(), captureListener, null);

                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onConfigureFailed(CameraCaptureSession session) {
                Log.w(TAG, "Failed to configure camera");
            }
        }, null);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    } finally {
        takePictureButton.setEnabled(false);
        mTextureView.setEnabled(false);
    }
...