Подтвердить что ты не робот

Не удалось подключиться к службе камеры

У меня установлена ​​камера на this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);, и она работает нормально, но если я изменю ее на PORTRAIT вместо LANDSCAPE, тогда она выйдет со следующей ошибкой...

07-30 12:51:37.655: ERROR/AndroidRuntime(22069): FATAL EXCEPTION: main
07-30 12:51:37.655: ERROR/AndroidRuntime(22069): java.lang.RuntimeException: Fail to connect to camera service
07-30 12:51:37.655: ERROR/AndroidRuntime(22069):     at android.hardware.Camera.native_setup(Native Method)
07-30 12:51:37.655: ERROR/AndroidRuntime(22069):     at android.hardware.Camera.<init>(Camera.java:110)
07-30 12:51:37.655: ERROR/AndroidRuntime(22069):     at android.hardware.Camera.open(Camera.java:90)
07-30 12:51:37.655: ERROR/AndroidRuntime(22069):     at org.digital.com.CamLayer.surfaceCreated(CamLayer.java:3

Метод, с которым он падает, - это...

public void surfaceCreated(SurfaceHolder holder) {
    synchronized(this) {
        mCamera = Camera.open();

        Camera.Parameters p = mCamera.getParameters(); 
        p.setPreviewSize(800, 480);
        mCamera.setParameters(p);

        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            Log.e("Camera", "mCamera.setPreviewDisplay(holder);");
        }

        mCamera.startPreview();
        mCamera.setPreviewCallback(this);
    }
}

Сбой при mCamera = Camera.open();

Мой файл манифеста имеет <uses-permission android:name="android.permission.CAMERA"></uses-permission>

Как исправить это, чтобы я мог просматривать свое приложение в портрете?

4b9b3361

Ответ 1

Для вашей справки это внутренний класс SurfaceHolderCallBack, который я использую в своем приложении, и который отлично работает на Nexus One 2.2 в портретном режиме - надеюсь, что это поможет.

Изменить: "который работает" = "который не сбой". Хотя я не понял, как правильно повернуть изображение предварительного просмотра (см. Мой первый комментарий выше). Вот почему мне на самом деле пришлось использовать ландшафт и "конвертировать" пользовательский интерфейс, окружающий поверхность предварительного просмотра в ландшафтном режиме. Предварительный просмотр Afaik (с правильным вращением изображения предварительного просмотра) работает только в ландшафтном режиме. Параметры поворота и ориентации, которые я пытался, не помогли.

class SurfaceHolderCallback implements SurfaceHolder.Callback {
    private static final int IMAGE_WIDTH = 512;
    private static final int IMAGE_HEIGHT = 384;
    private static final String ORIENTATION = "orientation";
    private static final String ROTATION = "rotation";
    private static final String PORTRAIT = "portrait";
    private static final String LANDSCAPE = "landscape";

    public void surfaceCreated(SurfaceHolder holder) {
        try {
            // This case can actually happen if the user opens and closes the camera too frequently.
            // The problem is that we cannot really prevent this from happening as the user can easily
            // get into a chain of activites and tries to escape using the back button.
            // The most sensible solution would be to quit the entire EPostcard flow once the picture is sent.
            camera = Camera.open();
        } catch(Exception e) {
            finish();
            return;
        }

        //Surface.setOrientation(Display.DEFAULT_DISPLAY,Surface.ROTATION_90);
        Parameters p = camera.getParameters();
        p.setPictureSize(IMAGE_WIDTH, IMAGE_HEIGHT);

        camera.getParameters().setRotation(90);

        Camera.Size s = p.getSupportedPreviewSizes().get(0);
        p.setPreviewSize( s.width, s.height );

        p.setPictureFormat(PixelFormat.JPEG);
        p.set("flash-mode", "auto");
        camera.setParameters(p);

        try {
            camera.setPreviewDisplay(surfaceHolder);
        } catch (Throwable ignored) {
            Log.e(APP, "set preview error.", ignored);
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
        if (isPreviewRunning) {
            camera.stopPreview();
        }
        try {
            camera.startPreview();
        } catch(Exception e) {
            Log.d(APP, "Cannot start preview", e);    
        }
        isPreviewRunning = true;
    }

    public void surfaceDestroyed(SurfaceHolder arg0) {
        if(isPreviewRunning && camera != null) {
            if(camera!=null) {
                camera.stopPreview();
                camera.release();  
                camera = null;
            }
            isPreviewRunning = false;
        }
    }
}

Ответ 2

В платформе есть проблема с concurrency: http://code.google.com/p/android/issues/detail?id=6201

Обходной путь - очистить обратный вызов перед выпуском кулачка, то есть я рекомендую следующий код очистки:

    @Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (mCam != null) {
        mCam.stopPreview();
        mCam.setPreviewCallback(null);
        mCam.release();
        mCam = null;
    }
}

Ответ 3

У вас есть этот набор в AndroidManifest.xml?

uses-permission android:name="android.permission.CAMERA"

Ответ 4

Вместо использования:

<uses-permission
    android:name="android.permission.FLASHLIGHT"/>

Попробуйте использовать:

<uses-permission
    android:name="android.permission.FLASHLIGHT"
    android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
    android:protectionLevel="normal" />

и не забудьте добавить разрешение для камеры:

<uses-permission android:name="android.permission.CAMERA" />

Ответ 5

Я вижу, что вы установили область предварительного просмотра как 800 x 480. В портретном режиме этот размер недопустим, и в API может быть ошибка, из-за которой он сбой.

Попробуйте установить область предварительного просмотра размером 200x200

Ответ 6

Я думаю, ваша проблема в том, что когда вы вращаете камеру, она не выпускается правильно или вообще. Если вы переключаетесь с landscape на portrait, Intent запускается снова. Если затем камера не отпущена и повторно откроется, вы попытаетесь открыть уже открытую камеру, которая выдает сообщение об ошибке.

Ответ 7

Другая возможность, если вы используете эмулятор Android, может заключаться в том, что передняя и задняя камеры определены как "нет" в настройках виртуального устройства Android.