这是我的表面更改事件处理代码:
public void surfaceChanged(SurfaceHolder holder,
int format, int width,
int height) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height,
parameters);
//...
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result = null;
// it fails with NullPointerExceptiopn here,
// when accessing "getSupportedPreviewSizes" method:
// that means "parameters" is null
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
///...
}
}
我像这样初始化相机:
@Override
public void onResume() {
super.onResume();
camera = Camera.open();
}
我的Galaxy S Plus上不会出现此问题,也不会发生在LG Optimus Black手机上。有谁想过这里有什么问题?
答案 0 :(得分:3)
我已经解决了这个问题。
parameters.getSupportedPreviewSizes()
在Galaxy Tab上返回NULL。所以我只是检查它是否为null并且在这种情况下不设置新的预览大小。为此,我在查看标准相机应用程序源之后来到了这里。
答案 1 :(得分:0)
看起来相机变量从未被初始化,所以你在null上调用getParameters()。请先尝试拨打camera = Camera.open();
答案 2 :(得分:-1)
相机初始化很大程度上取决于具体设备。例如,特定的三星设备GT5500报告null(width = 0,height = 0)作为预览的有效分辨率,但如果您尝试使用它,则会崩溃整个手机(“硬”重启)。我们使用mixare增强现实引擎(http://www.mixare.org)来体验它,并且它是PITA进行调试(因为我们没有手机,无法在任何其他硬件上重现该错误)。
但是,关于获得“正确”的预览大小,您可以在github上查看我们的代码(它是一个免费的开源应用程序)。在文件中:https://github.com/mixare/mixare/blob/master/src/org/mixare/MixView.java(第871行及以后)
List<Camera.Size> supportedSizes = null;
//On older devices (<1.6) the following will fail
//the camera will work nevertheless
supportedSizes = Compatibility.getSupportedPreviewSizes(parameters);
//preview form factor
float ff = (float)w/h;
Log.d("Mixare", "Screen res: w:"+ w + " h:" + h + " aspect ratio:" + ff);
//holder for the best form factor and size
float bff = 0;
int bestw = 0;
int besth = 0;
Iterator<Camera.Size> itr = supportedSizes.iterator();
//we look for the best preview size, it has to be the closest to the
//screen form factor, and be less wide than the screen itself
//the latter requirement is because the HTC Hero with update 2.1 will
//report camera preview sizes larger than the screen, and it will fail
//to initialize the camera
//other devices could work with previews larger than the screen though
while(itr.hasNext()) {
Camera.Size element = itr.next();
//current form factor
float cff = (float)element.width/element.height;
//check if the current element is a candidate to replace the best match so far
//current form factor should be closer to the bff
//preview width should be less than screen width
//preview width should be more than current bestw
//this combination will ensure that the highest resolution will win
Log.d("Mixare", "Candidate camera element: w:"+ element.width + " h:" + element.height + " aspect ratio:" + cff);
if ((ff-cff <= ff-bff) && (element.width <= w) && (element.width >= bestw)) {
bff=cff;
bestw = element.width;
besth = element.height;
}
}
Log.d("Mixare", "Chosen camera element: w:"+ bestw + " h:" + besth + " aspect ratio:" + bff);
//Some Samsung phones will end up with bestw and besth = 0 because their minimum preview size is bigger then the screen size.
//In this case, we use the default values: 480x320
if ((bestw == 0) || (besth == 0)){
Log.d("Mixare", "Using default camera parameters!");
bestw = 480;
besth = 320;
}
parameters.setPreviewSize(bestw, besth);
如您所见,我们没有直接使用Camera类的getSupportedPreviewSizes调用,而是添加了一个兼容层(代码在这里:https://github.com/mixare/mixare/blob/master/src/org/mixare/Compatibility.java),因为我们需要与旧手机兼容。如果您不想支持较旧的Android版本,可以直接使用Camera类的方法。
HTH 丹尼尔