27

I copied the code from the answer here and I still am getting a RuntimeException: setParameters failed error on my nexus one. My manifest file has camera and wake_lock permissions. This works on the emulator, and on the droid I don't get the error but it does have a rotation problem.

Community
  • 1
  • 1
Erik B
  • 2,810
  • 1
  • 34
  • 38

7 Answers7

41

You're most likely requsting an invalid preview size. If you check the results of adb logcat you'll probably see something like this:

E/QualcommCameraHardware(22732): Invalid preview size requested: 480x724

The solution is to request the closest available preview size to the one you'd like; you can get a list of available preview sizes by calling getSupportedPreviewSizes in the Camera.Parameters object returned by Camera.getParameters.

Roman Nurik
  • 29,665
  • 7
  • 84
  • 82
  • You are right, except that it was trying to set it to 320x480 and 480x320 would have worked. This brings me to my next question, why was the SurfaceHolder.Callback.surfaceChanged() method called with such a low resolution that doesn't even match the aspect ratio of the device? – Erik B Jan 15 '10 at 02:33
  • 2
    @Erik B -- I realize this is WAY late of a response to this comment, but it's likely because your app is in compatibility mode, and the system is treating pixels in your app as 0.66x the actual device resolution. So 480x800 will be presented to your app as 320x533, probably shaving a few pixels off horizontally or vertically for the status bar unless your activity is fullscreen. – Roman Nurik Oct 24 '10 at 04:01
  • What do you do before API version 5 ? (Let's say I want to be compatible with android 1.5) – uvgroovy Nov 04 '10 at 23:41
  • Tnx dude. Now need to find the way to make to run on multiple devices, dynamically. :D – stackflow Apr 08 '16 at 03:28
26

I corrected this by doing what Roman said, with the code:

   Camera.Parameters parameters = camera.getParameters();  
   List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();  
   Camera.Size cs = sizes.get(0);  
   parameters.setPreviewSize(cs.width, cs.height);  
   camera.setParameters(parameters);
Michael Celey
  • 12,645
  • 6
  • 57
  • 62
Sam
  • 261
  • 3
  • 2
10

For what it's worth, the source of my issue ended up being that I was trying to call parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); without first verifying that flash modes were supported by checking that parameters.getFlashMode() != null.

There's more than one cause for this poorly documented exception, so check all of your parameters and not just that you're using a supportedPreviewSize.

Andrew Coonce
  • 1,557
  • 11
  • 19
  • 1
    if (!getBaseContext().getPackageManager().hasSystemFeature( PackageManager.FEATURE_CAMERA_FLASH)) { // Camera flash is not available on the device } – Dhananjay M Oct 14 '15 at 10:40
3

None of the above solved this for me. Adding this code before setting the parameters did though.

// stop preview before making changes
    try {
        mCamera.stopPreview();
    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
    }

//now set your parameters
aaronmarino
  • 3,723
  • 1
  • 23
  • 36
2

For me this would happen after taking a photo and the preview would freeze, until I updated my call for parameters to be the following. It is always important with this error to make sure you check all of the parameters that the camera is asking to set to make sure that every parameter you are asking the camera to set itself to is possible for the camera.

Camera.Parameters parameters = myCamera.getParameters();

With the preview size:

if (myCamera.getParameters().getSupportedPreviewSizes() != null){
     Camera.Size previewSize = getOptimalPreviewSize(myCamera.getParameters().getSupportedPreviewSizes(), width, height);;
     parameters.setPreviewSize(previewSize.width, previewSize.height);
}

With the flash/focus modes:

if(parameters.getSupportedFocusModes() != null && parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
     parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}

if (parameters.getSupportedFlashModes() != null && parameters.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_AUTO)){
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);

}

myCamera.setParameters(parameters);

etc. All of this wrapped in a nice try{}catch(){} works great. Good luck.

Here is the getOptimalPreview Size from this great tutorial:

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height)
    {
        // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails
        Camera.Size optimalSize = null;

        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) height / width;

        // Try to find a size match which suits the whole screen minus the menu on the left.
        for (Camera.Size size : sizes){

            if (size.height != width) continue;
            double ratio = (double) size.width / size.height;
            if (ratio <= targetRatio + ASPECT_TOLERANCE && ratio >= targetRatio - ASPECT_TOLERANCE){
                optimalSize = size;
            }
        }

        // If we cannot find the one that matches the aspect ratio, ignore the requirement.
        if (optimalSize == null) {
            // TODO : Backup in case we don't get a size.
        }

        return optimalSize;
    }
Priya Singhal
  • 1,261
  • 11
  • 16
Chris Klingler
  • 5,258
  • 2
  • 37
  • 43
0

Some open source camera project like opencamera always use try-catch to call Camera.setParameters:

private void setCameraParameters(Camera.Parameters parameters) {
    if( MyDebug.LOG )
        Log.d(TAG, "setCameraParameters");
    try {
        camera.setParameters(parameters);
        if( MyDebug.LOG )
            Log.d(TAG, "done");
    } catch (RuntimeException e) {
        // just in case something has gone wrong
        if( MyDebug.LOG )
            Log.d(TAG, "failed to set parameters");
        e.printStackTrace();
        count_camera_parameters_exception++;
    }
}

in addition,always get the latest getParameters before you call setParameters like this:

void setRotation(int rotation) {
    Camera.Parameters parameters = this.getParameters();
    parameters.setRotation(rotation);
    setCameraParameters(parameters);
}
sajjadG
  • 2,546
  • 2
  • 30
  • 35
bang_chen
  • 11
  • 1
0

the solution from Sam is correct but the output image is still zoomed a little bit on several tablet devices. One of the best practices that I found on Internet, we should set in Camera host so that the properties will be re-used each time the camera is resumed. Here is implemented method in CameraHost:

@Override
        public Parameters adjustPreviewParameters(Parameters parameters) {
            List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
            Camera.Size cs = sizes.get(0);
            parameters.setPreviewSize(cs.width, cs.height);
            return super.adjustPreviewParameters(parameters);
        }
Long Thay
  • 13
  • 5