我从这里的答案复制了代码,但我在我的Nexus One上仍然遇到一个RuntimeException:setParameters failed错误。我的清单文件具有相机和wake_lock权限。这在模拟器上有效,在Droid上没有错误,但它确实存在旋转问题。
您很可能请求了一个无效的预览尺寸。如果您检查adb logcat
的结果,您可能会看到类似以下的内容:
E/QualcommCameraHardware(22732): Invalid preview size requested: 480x724
解决方案是请求与所需预览尺寸最接近的可用尺寸;您可以通过调用由Camera.getParameters返回的Camera.Parameters对象中的getSupportedPreviewSizes
方法来获取可用的预览尺寸列表。我按照 Roman 所说的方法进行了更正,使用了以下代码:
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);
说实话,我的问题源头在于我试图调用parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
之前没有先验证闪光模式是否受支持,需要检查 parameters.getFlashMode() != null
。
由于存在多种原因导致此异常文档不完整,因此请检查所有参数,而不仅仅是使用了supportedPreviewSize
。
以上方法都没有解决我的问题。但在设置参数之前添加以下代码可以解决。
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
//now set your parameters
对我来说,这种情况发生在我拍照后预览界面会卡住,直到我更新了参数设置为以下内容。在遇到此错误时,始终重要的是确保您检查相机要求设置的所有参数,以确保您要求相机设置自身的每个参数都对相机可行。
Camera.Parameters parameters = myCamera.getParameters();
预览大小为:
if (myCamera.getParameters().getSupportedPreviewSizes() != null){
Camera.Size previewSize = getOptimalPreviewSize(myCamera.getParameters().getSupportedPreviewSizes(), width, height);;
parameters.setPreviewSize(previewSize.width, previewSize.height);
}
使用闪光灯/对焦模式:
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);
等等,所有这些都包含在一个很好的try{}catch(){}中运行得很好。祝你好运。
这里是从这篇优秀教程中获取OptimalPreview Size的方法:
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height)
{
// Source: https://dev59.com/m-o6XIcBkEYKwwoYSCc1
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;
}
Sam的解决方案是正确的,但在一些平板设备上输出图像仍然有点缩放。我在互联网上找到的最佳实践之一是,在Camera主机中设置属性,以便每次恢复相机时都可以重用这些属性。以下是在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);
}
try-catch
来调用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++;
}
}
此外,在调用setParameters
之前,始终获取最新的getParameters
,如下所示:
void setRotation(int rotation) {
Camera.Parameters parameters = this.getParameters();
parameters.setRotation(rotation);
setCameraParameters(parameters);
}