我正在使用OpenCV library
开发一个简单的AR应用程序,我已经为我的原生部分做得很好,并成功运行在genymotion模拟器中。但是,当我希望部署到我的device (SONY C2105 - Android 4.2.2 same as emulator version)
时,它就失败了。
03-21 16:25:05.118: E/AndroidRuntime(26424): FATAL EXCEPTION: main
03-21 16:25:05.118: E/AndroidRuntime(26424): Process: com.example.detectimage, PID: 26424
03-21 16:25:05.118: E/AndroidRuntime(26424): java.lang.NullPointerException
03-21 16:25:05.118: E/AndroidRuntime(26424): at com.example.detectimage.CameraPreview.surfaceCreated(CameraPreview.java:68)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.SurfaceView.updateWindow(SurfaceView.java:572)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.SurfaceView.access$000(SurfaceView.java:86)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:175)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1871)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.Choreographer.doCallbacks(Choreographer.java:574)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.Choreographer.doFrame(Choreographer.java:544)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.os.Handler.handleCallback(Handler.java:733)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.os.Handler.dispatchMessage(Handler.java:95)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.os.Looper.loop(Looper.java:136)
03-21 16:25:05.118: E/AndroidRuntime(26424): at android.app.ActivityThread.main(ActivityThread.java:5017)
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private Camera mCamera;
private SurfaceHolder mHolder;
private int mFrameWidth;
private int mFrameHeight;
private Handler mHandler;
public CameraPreview(Context context, Handler handler) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHandler = handler;
Log.i(TAG, "Instantiated new " + this.getClass());
}
public void surfaceChanged(SurfaceHolder _holder, int format, int width,
int height) {
Log.i(TAG, "surfaceCreated");
if (mCamera != null) {
Camera.Parameters params = mCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
mFrameWidth = width;
mFrameHeight = height;
// selecting optimal camera preview size
{
double minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - height) < minDiff) {
mFrameWidth = size.width;
mFrameHeight = size.height;
minDiff = Math.abs(size.height - height);
}
}
}
params.setPreviewSize(mFrameWidth, mFrameHeight);
mCamera.setParameters(params);
mCamera.startPreview();
}
}
public void surfaceCreated(SurfaceHolder holder) {
Log.i(TAG, "surfaceCreated");
mCamera = Camera.open();
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.setOneShotPreviewCallback(mCallback);
}
private PreviewCallback mCallback = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Message msg = new Message();
msg.arg1 = detectImage(mFrameWidth, mFrameHeight, data);
mHandler.sendMessage(msg);
}
};
public void restartPreviewCallback(){
this.requestLayout();
this.invalidate();
if (mCamera != null) {
mCamera.setOneShotPreviewCallback(mCallback);
mCamera.startPreview();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i(TAG, "surfaceDestroyed");
if (mCamera != null) {
synchronized (this) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
}
public native int detectImage(int width, int height, byte[] data);
static {
System.loadLibrary("opencv_java");
System.loadLibrary("native_sample");
}
}
答案 0 :(得分:0)
首先检查清单文件中的以下权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
然后检查您的手机是否支持相机,
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
如果为true,则在CameraPreview构造函数中获取相机实例,并将代码分配给代码中的mCamera实例。
mCamera = getCameraInstance();
//需要一些小的延迟来获取实例
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
public void surfaceCreated(SurfaceHolder holder) {
Log.i(TAG, "surfaceCreated");
if(mCamera == null)
mCamera = getCameraInstance();
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.setOneShotPreviewCallback(mCallback);
}