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

У меня установлена ​​моя камера 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>

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

Solutions Collecting From Web of "Не удалось подключиться к службе камеры"

Для вашей справки это внутренний класс 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; } } } 

В платформе есть проблема с параллелизмом: 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; } } 

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

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

Вместо того, чтобы использовать :

 <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" /> 

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

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

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

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