While developing a camera app I\'ve encountered an exception that only happened when I switch to other app (onPause()
for my app).
01-15 17:22:1
To Resume correctly, you need to do this:
@Override
public void onResume() {
super.onResume();
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera initialization
}
}
protected void initializeCamera(){
// Get an instance of Camera Object
mCamera = getCameraInstance();
// create a basic camera preview class that can be included in a View layout.
mPreview=new CameraPreview(this,mCamera);
//add your preview class to the FrameLayout element.
preview.addView(mPreview);
//Trigger capturing an image by calling the Camera.takePicture() method.
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
And also just to remind that in oncreate() do nothing except defining FrameLayout preview and Button captureButton.
I've got the same problem. mCamera.setPreviewCallback(null);
didn't help. In my activity I've added this to releaseCamera
:
mPreview.getHolder().removeCallback(mPreview);
and it works now.
@Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
this.getHolder().removeCallback(this);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
Log.e("surfaceDestroyed", "surfaceDestroyed");
}
And re initialize the camera in on Resume function.
I have put
mPreview.getHolder().removeCallback(mPreview);
between.
mCamera.setPreviewCallback(null);
and
mCamera.release();
and it worked for me.
@Override
protected void onPause() {
super.onPause();
this.saveTextEdits();
try {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
**mPreview.getHolder().removeCallback(mPreview);**
mCamera.release();
mCamera = null;
}catch (Exception e){
}
}
@ookami.kb solution worked for me too, as well as @srunni commented.
public void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mPreview.getHolder().removeCallback(mPreview);
mCamera.release();
}
}
I removed onDestroy method too.
Adding to okambi's answer.
This is the function messing everything up when you resume:
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
The try{} is not catching the exception being thrown. Namely that mCamera doesn't exist, and then when it tries to call setPreviewDisplay(holder), there is a crash.
So by removing the callback, this surfaceCreated doesn't get called and avoids the crash.
This is VERY POORLY DOCUMENTED by Google.