I have one activity class(CameraActivity) which is using my CameraPreview class. In "OnResume" the camera and preview are initiated. In "OnPause", i am releasing camera resources. When application is started, everything works fine inside the "OnResume" but when i start another activity through intent (E.g. open url in browser) and then come back to my activity then exception is occured inside "OnResume" originating CamerPreview class. Please find below the code:
//CameraActivity class
public void onResume(){
super.onResume();
Log.d("inside onResume, camera==="+mCamera, "inside onResume");
try {
if(mCamera==null)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
autoFocusHandler = new Handler();
mCamera = getCameraInstance();
int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("onResume",Log.getStackTraceString(e));
}
public void onPause{
try {
super.onPause();
if (mCamera != null) {
previewing = false;
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
mPreview=null;
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("releaseCamera",Log.getStackTraceString(e));
}
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open();
} catch (Exception e){
Log.e("getCameraInstance",Log.getStackTraceString(e));
}
return c;
}
// Following is CameraPreview Class:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
Camera mCamera;
PreviewCallback previewCallback;
AutoFocusCallback autoFocusCallback;
private int rotation;
public int getRotation() {
return rotation;
}
public void setRotation(int rotation) {
this.rotation = rotation;
}
public CameraPreview(Context context, Camera camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
super(context);
mCamera = camera;
previewCallback = previewCb;
autoFocusCallback = autoFocusCb;
/*
* Set camera to continuous focus if supported, otherwise use
* software auto-focus. Only works for API level >=9.
*/
/*
Camera.Parameters parameters = camera.getParameters();
for (String f : parameters.getSupportedFocusModes()) {
if (f == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
autoFocusCallback = null;
break;
}
}
*/
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
if(mCamera==null){
mCamera=Camera.open();
}
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
Log.d("DBG", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Camera preview released in activity
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
/*
* If your preview can change or rotate, take care of those events here.
* Make sure to stop the preview before resizing or reformatting it.
*/
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);
} catch (Exception e){
Log.d("DBG", "Error starting camera preview: " + e.getMessage());
}
}
}
This is from logCat:
11-05 10:14:34.585: E/AndroidRuntime(7864): FATAL EXCEPTION: main
11-05 10:14:34.585: E/AndroidRuntime(7864): java.lang.RuntimeException: Method called after release()
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.hardware.Camera.setPreviewDisplay(Native Method)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.hardware.Camera.setPreviewDisplay(Camera.java:393)
11-05 10:14:34.585: E/AndroidRuntime(7864): at com.intagleo.qraugmented.detection.camera.CameraPreview.surfaceCreated(CameraPreview.java:74)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.SurfaceView.updateWindow(SurfaceView.java:552)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:215)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.View.dispatchWindowVisibilityChanged(View.java:4027)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewRoot.performTraversals(ViewRoot.java:790)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.os.Handler.dispatchMessage(Handler.java:99)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.os.Looper.loop(Looper.java:130)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.app.ActivityThread.main(ActivityThread.java:3687)
11-05 10:14:34.585: E/AndroidRuntime(7864): at java.lang.reflect.Method.invokeNative(Native Method)
11-05 10:14:34.585: E/AndroidRuntime(7864): at java.lang.reflect.Method.invoke(Method.java:507)
11-05 10:14:34.585: E/AndroidRuntime(7864): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
11-05 10:14:34.585: E/AndroidRuntime(7864): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
11-05 10:14:34.585: E/AndroidRuntime(7864): at dalvik.system.NativeStart.main(Native Method)
EDIT
I updated "surfaceDestroyed" and put logs as suggested but now i am getting exception in "onPause" --> onSurfaceDestroyed. Initially onPause was executing fine.
1- The camera instance is created in "onResume" of activity class through method "getCameraInstance" and passes mCamera instance to CameraPreview Class. I tried to change it so that camera instance is created only onside "onSurfaceCreated" and assigned back the mCamera instance to the activity class but it did not work. I also noticed through debug that previewCallBack member of "CameraPreview" class is valid the first time but second time the "previewCallBack" member of "CameraPreview" class is null.
Note that first time when "onResume" is called, everything works fine but when it runs second time after onPause then exception is occured originally although code is the same in onResume.
11-06 01:25:28.375: I/onResume(4332): INITIATED
// Workinf fine till now. Now opening another intent activity
11-06 01:26:23.500: I/onPause(4332): INITIATED
11-06 01:26:23.804: "OnSurfaceDestroyed": "Initiated"
11-06 01:26:23.945: E/AndroidRuntime(4332): FATAL EXCEPTION: main
11-06 01:26:23.945: E/AndroidRuntime(4332): java.lang.RuntimeException: Method called after release()
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.hardware.Camera.stopPreview(Native Method)
11-06 01:26:23.945: E/AndroidRuntime(4332): at com.intagleo.qraugmented.detection.camera.CameraPreview.surfaceDestroyed(CameraPreview.java:85)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:596)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.SurfaceView.updateWindow(SurfaceView.java:490)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:215)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.View.dispatchWindowVisibilityChanged(View.java:4027)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewRoot.performTraversals(ViewRoot.java:790)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.os.Handler.dispatchMessage(Handler.java:99)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.os.Looper.loop(Looper.java:130)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.app.ActivityThread.main(ActivityThread.java:3687)
11-06 01:26:23.945: E/AndroidRuntime(4332): at java.lang.reflect.Method.invokeNative(Native Method)
11-06 01:26:23.945: E/AndroidRuntime(4332): at java.lang.reflect.Method.invoke(Method.java:507)
11-06 01:26:23.945: E/AndroidRuntime(4332): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
11-06 01:26:23.945: E/AndroidRuntime(4332): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
11-06 01:26:23.945: E/AndroidRuntime(4332): at dalvik.system.NativeStart.main(Native Method)
See Question&Answers more detail:
os