Skizit
Skizit

Reputation: 44862

Fail to connect to camera service

I had my camera set to this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); and it works fine but if I change it to PORTRAIT instead of LANDSCAPE then it crashes with the following error...

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

The method it crashes in is..

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

It crashes at mCamera = Camera.open();

My Manifest file has <uses-permission android:name="android.permission.CAMERA"></uses-permission>

How do I fix this so I can view my app in Portrait?

Upvotes: 13

Views: 35769

Answers (8)

MJakhongir
MJakhongir

Reputation: 3028

this might work...

   @Override public void surfaceDestroyed(SurfaceHolder holder) {
    Log.d("surfaceDestroyed", "");
    cameraSource.stop();   //check if you have this line
  }

Upvotes: 0

Dave Burke
Dave Burke

Reputation: 21

Another possibility if you're using an Android Emulator may be that the front and back cameras are defined as "none" in the Android Virtual Device settings.

Upvotes: 1

Tom Groentjes
Tom Groentjes

Reputation: 1113

I think your problem is that when you rotate the camera it is not released correctly or at all. If you switch from landscape to portrait the Intent is launched again. If then the camera is not released and reopend you try to open an already open camera, which throws an error.

Upvotes: 0

Vaibhav
Vaibhav

Reputation: 123

Instead of using :

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

Try to use:

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

and don't forget to add the permission for camera:

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

Upvotes: 2

Romain Hippeau
Romain Hippeau

Reputation: 24375

Do you have this set in AndroidManifest.xml ?

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

Upvotes: 13

Krzysztof Madejski
Krzysztof Madejski

Reputation: 8027

There is some concurrency problem in platform: http://code.google.com/p/android/issues/detail?id=6201

The workaround is to clear callback before releasing cam, that is I would recommend following clean-up code:

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

Upvotes: 24

Mathias Conradt
Mathias Conradt

Reputation: 28705

For your reference, this is the SurfaceHolderCallBack inner class that I'm using in my app and which works fine on Nexus One 2.2 in portrait mode - hope it helps.

Edit: "which works" = "which doesn't crash". Although I haven't figured out how to rotate the preview image correctly (see my first comment above). That's why I actually had to use landscape and 'convert' UI stuff that's surrounding the preview surface into landscape mode. Afaik preview (with correct rotation of the preview image) only works in landscape mode. Rotation & orientation params that I tried didn't help at all.

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

Upvotes: 16

the100rabh
the100rabh

Reputation: 4147

I see you have set your preview area set as 800 x 480. In portrait mode, this size is invalid and there might be a bug in the API which makes it crash.

Try setting a preview area of 200x200

Upvotes: -1

Related Questions