简体   繁体   中英

RuntimeException on Camera.setParameters() on nexus one

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.

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 .

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

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 .

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

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM