13

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?

Marko
  • 20,385
  • 13
  • 48
  • 64
Skizit
  • 43,506
  • 91
  • 209
  • 269
  • 1
    What device are you working on and what SDK version? Afaik camera preview only works properly in landscape mode, but in portrait. I also wanted to use it in portrait mode (on N1, on Samsung Galaxy S), but without success. Also see the bug tracker at http://code.google.com/p/android/issues/detail?id=1193; although I never got an error like you mentioned above. – Mathias Conradt Aug 01 '10 at 14:45
  • Do you have another device to test it on? Does it work in Emulator? if it's a small apk, I can help you test it on my N1 and Galaxy S. Your 2.2 is the final 2.2 FRF91? – Mathias Conradt Aug 03 '10 at 11:24
  • i m facing the same problem at the same line.The exception does not always occur but it happens sometime.Can anybody explain why it crashes sometime not always.....? i m using Samsung gt-s5360 – picaso Mar 23 '12 at 11:52
  • Skizit can you please help me regarding http://stackoverflow.com/questions/26714771/android-camera-take-picture-failed-issue – koutuk Nov 04 '14 at 05:49

8 Answers8

24

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;
    }
}
Kangur
  • 7,823
  • 3
  • 30
  • 32
  • Kangur ... can you please help me regarding http://stackoverflow.com/questions/26714771/android-camera-take-picture-failed-issue – koutuk Nov 04 '14 at 05:48
  • Sorry, I haven't been androiding since 3 years.. No idea how does it work now :) – Kangur Dec 22 '14 at 08:12
16

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 Conradt
  • 28,420
  • 21
  • 138
  • 192
  • Mathias Lin ... can you please help me regarding http://stackoverflow.com/questions/26714771/android-camera-take-picture-failed-issue – koutuk Nov 04 '14 at 05:49
  • Where did you implent the finish method (in catch block) and what it does ? – emin deniz May 31 '16 at 10:37
13

Do you have this set in AndroidManifest.xml ?

uses-permission android:name="android.permission.CAMERA"
Reno
  • 33,594
  • 11
  • 89
  • 102
Romain Hippeau
  • 24,113
  • 5
  • 60
  • 79
  • 2
    Thanks for posting this, even if it's obvious, it is a useful tip for some people searching for this (like me). – Dimitris Sep 15 '13 at 22:56
  • Romain Hippeau ... can you please help me regarding http://stackoverflow.com/questions/26714771/android-camera-take-picture-failed-issue – koutuk Nov 04 '14 at 05:47
2

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" />
Vaibhav
  • 123
  • 1
  • 6
1

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.

Dave Burke
  • 21
  • 1
  • 4
0

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.

Raghav Sood
  • 81,899
  • 22
  • 187
  • 195
Tom Groentjes
  • 1,053
  • 8
  • 7
0

this might work...

   @Override public void surfaceDestroyed(SurfaceHolder holder) {
    Log.d("surfaceDestroyed", "");
    cameraSource.stop();   //check if you have this line
  }
MJakhongir
  • 2,101
  • 2
  • 16
  • 27
-1

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
  • 4,077
  • 4
  • 32
  • 40
  • 1
    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 Conradt Aug 02 '10 at 06:16
  • Yeah, this doesn't fix anything. It breaks my set params. – Skizit Aug 02 '10 at 11:20
  • 1
    you have to find the optimal preview size get all sizes compare and get the biggest one and it will work, – Toshe Jan 31 '12 at 10:09
  • the100rabh ... can you please help me regarding http://stackoverflow.com/questions/26714771/android-camera-take-picture-failed-issue – koutuk Nov 04 '14 at 05:48