tags:

views:

113

answers:

3

Hey guys,

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?

A: 

Do you have this set in AndroidManifest.xml ?
uses-permission android:name="android.permission.CAMERA"

Romain Hippeau
Yeah, I have that set.
Ulkmun
A: 

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

the100rabh
I tried 800x480 previewSize in above code sample as well, works ok on Nexus One 2.2. In fact 800x480 is the default size that you get on N1 when calling: p.getSupportedPreviewSizes().get(0); - therefore it's a correct preview size.
Mathias Lin
Yeah, this doesn't fix anything. It breaks my set params.
Ulkmun
+1  A: 

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