调用系统相机扫码时报错:app passed NULL surface java.lang.RuntimeException: startPreview failed
D/Camera: app passed NULL surface
W/System.err: java.lang.RuntimeException: startPreview failed
W/System.err: at android.hardware.Camera.startPreview(Native Method)
W/System.err: at com.gritview.mycamera.CameraManager.startPreview(CameraManager.java:116)
W/System.err: at com.gritview.mycamera.CameraPreview.startCameraPreview(CameraPreview.java:97)
W/System.err: at com.gritview.mycamera.CameraPreview.surfaceChanged(CameraPreview.java:114)
W/System.err: at android.view.SurfaceView.updateWindow(SurfaceView.java:621)
W/System.err: at android.view.SurfaceView.access$000(SurfaceView.java:93)
W/System.err: at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:182)
W/System.err: at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:864)
W/System.err: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2138)
W/System.err: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1245)
W/System.err: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6320)
W/System.err: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
W/System.err: at android.view.Choreographer.doCallbacks(Choreographer.java:591)
W/System.err: at android.view.Choreographer.doFrame(Choreographer.java:561)
W/System.err: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
W/System.err: at android.os.Handler.handleCallback(Handler.java:730)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err: at android.os.Looper.loop(Looper.java:137)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5414)
W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err: at java.lang.reflect.Method.invoke(Method.java:525)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
W/System.err: at dalvik.system.NativeStart.main(Native Method)
I/Choreographer: Skipped 629 frames! The application may be doing too much work on its main thread.
W/System.err: java.lang.RuntimeException: startPreview failed
W/System.err: at android.hardware.Camera.startPreview(Native Method)
W/System.err: at com.gritview.mycamera.CameraManager.startPreview(CameraManager.java:116)
W/System.err: at com.gritview.mycamera.CameraPreview.startCameraPreview(CameraPreview.java:97)
W/System.err: at com.gritview.mycamera.CameraPreview.start(CameraPreview.java:80)
原始代码:
/**
* Camera start preview.
*/
public boolean start() {
try {
mCameraManager.openDriver();
} catch (Exception e) {
return false;
}
mPreviewCallback.onStart();
if (mSurfaceView == null) {
mSurfaceView = new SurfaceView(getContext());
addView(mSurfaceView, new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
SurfaceHolder holder = mSurfaceView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
startCameraPreview(mSurfaceView.getHolder());
return true;
}
其中: mCameraManager.openDriver();中的代码是初始化camera对象的:
/**
* Opens the mCamera driver and initializes the hardware parameters.
*
* @throws Exception ICamera open failed, occupied or abnormal.
*/
public synchronized void openDriver() throws Exception {
if (mCamera != null) return;
mCamera = Camera.open();
if (mCamera == null) throw new IOException("The camera is occupied.");
mConfiguration.initFromCameraParameters(mCamera);
Camera.Parameters parameters = mCamera.getParameters();
List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
for (Camera.Size size:supportedPreviewSizes) {
System.out.println(size.width + " ------- " + size.height);
}
String parametersFlattened = parameters == null ? null : parameters.flatten();
try {
mConfiguration.setDesiredCameraParameters(mCamera, false);
} catch (RuntimeException re) {
if (parametersFlattened != null) {
parameters = mCamera.getParameters();
parameters.unflatten(parametersFlattened);
try {
mCamera.setParameters(parameters);
mConfiguration.setDesiredCameraParameters(mCamera, true);
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
上面的代码在Android 有些版本上运行是没有问题,但是在使用三星 Android4.3测试的时候,会报异常,该异常的主要原因是:
在初始化Camera对象之前,没有指定SurfaceHolder对象的类型,所以只需要将上面的代码顺序调换一下即可:
正确代码如下:
/**
* Camera start preview.
*/
public boolean start() {
if (mSurfaceView == null) {
mSurfaceView = new SurfaceView(getContext());
addView(mSurfaceView, new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
SurfaceHolder holder = mSurfaceView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
startCameraPreview(mSurfaceView.getHolder());
try {
mCameraManager.openDriver();
} catch (Exception e) {
return false;
}
mPreviewCallback.onStart();
return true;
}