Сбой метода Camera.takePicture() на Nexus 5, но с Xperia mini все в порядке

Сначала, пожалуйста, извините мой плохой английский. У меня проблема с программным фотографированием. Я написал приложение, которое собирает фотографии на основе таймера обратного отсчета. и после этого фотографии обрабатываются с помощью кода C++.

Я использую фиктивный SurfaceView, потому что мне не нужен предварительный просмотр в пользовательском интерфейсе. Приведенный ниже код работает на моем телефоне Xperia mini — API 15 (поэтому разрешения и код будут правильными), но я позаимствовал школьный Nexus 5 — API 21, и есть проблема с предварительным просмотром.

takePicture: camera 0: Cannot take picture without preview enabled

Я нашел решение, в котором вместо setPreviewDisplay используется setPreviewTexture (см. ниже). Это работает для первой фотографии, которая обычно сохраняется, но я получаю ту же ошибку после второго вызова takePicture().

Спасибо за каждый совет, ЛС

Camera camera;
@Override
protected void onResume() {
    super.onResume();
    // is camera on device?
    if(!checkCameraHardware()) return;

    releaseCamera();
    try {
        camera.stopPreview();
    } catch (Exception e){
      Log.d(TAG, "No preview before.");
    }

    SurfaceView dummy = new SurfaceView(this);
    camera = Camera.open();
    Camera.Parameters params = camera.getParameters();
    params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
    camera.setParameters(params);

    try {
        //camera.setPreviewTexture(new SurfaceTexture(10));
        camera.setPreviewDisplay(dummy.getHolder());
    } catch (IOException e) {
        e.printStackTrace();
    }
    camera.startPreview();
}

РЕШЕНИЕ:

Мне нужно было обновить предварительный просмотр. Приведенный ниже код также работает на Xperie и Nexus. Остается вопрос, почему я должен использовать setPreviewTexture, потому что setPreviewDisplay всегда возвращает ошибку на Nexus.

    camera.takePicture(null, null, new PictureCallback() {
        @Override
        public void onPictureTaken(final byte[] data, Camera camera) {
            // save picture
            refreshPreview();
        }
    });

public void refreshPreview() {
    try {
        camera.stopPreview();
    } catch (Exception e) {}

    try {
        camera.startPreview();
    } catch (Exception e) {}
}

и в функции onResume()

try {
    camera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e) {}

person Lukas    schedule 15.04.2015    source источник
comment
Вам не нужен SurfaceView. См. stackoverflow.com/questions /22462360/   -  person fadden    schedule 22.04.2015


Ответы (2)


После того, как снимок будет сделан, обновите изображение, остановите предварительный просмотр, отпустите камеру и снова запустите процесс.

        try {
                camera.takePicture(null, null, new PictureCallback() {
            public void onPictureTaken(final byte[] data, Camera camera) {
                //once ur logic done
                refreshCamera();
            }
        });
            } catch (Exception e2) {
                // Toast.makeText(getApplicationContext(), "Picture not taken", Toast.LENGTH_SHORT).show();
                e2.printStackTrace();
            }

        public void refreshCamera() {
            if (dummy.getHolder().getSurface() == null) {
                return;
            }

            try {
                camera.stopPreview();
            } catch (Exception e) {
                // ignore: tried to stop a non-existent preview
            }

            try {
                camera.setPreviewDisplay(dummy.getHolder());
                camera.startPreview();
            } catch (Exception e) {

            }
        }

Надеюсь, это решение может вам помочь.

person Harsha Vardhan    schedule 15.04.2015

Просто добавьте обратный вызов для запуска предварительного просмотра на вашем экземпляре камеры. Дело в том, что после запуска предпросмотра на экземпляре камеры ему нужно некоторое время, чтобы сделать снимок. Попробуй это:

           camera.startPreview();
            camera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                    camera.takePicture(null, null, new Camera.PictureCallback() {
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera) {
                   // do something you want with your picture and stop preview
                            camera.stopPreview();
                        }
                    });
person Samvel Kartashyan    schedule 01.07.2015