Every time I exit/pause my camera activity, my application crashes. I think it may have something to do with releasing the camera on pause/exit, but I’m not sure where exactly to do it. An explanation would be much appreciated. Thanks!
CameraActivity.java
public class CameraActivity extends Activity {
Preview preview;
Button buttonClick;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview = new Preview(this);
((FrameLayout) findViewById(R.id.preview)).addView(preview);
buttonClick = (Button) findViewById(R.id.buttonClick);
buttonClick.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
preview.camera.takePicture(shutterCallback, rawCallback,
jpegCallback);
}
});
}
ShutterCallback shutterCallback = new ShutterCallback() {
@Override
public void onShutter() {
}
};
PictureCallback rawCallback = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
}
};
PictureCallback jpegCallback = new PictureCallback() { // <8>
@Override
public void onPictureTaken(byte[] data, Camera camera) {
doSomeStuff();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
camera.stopPreview();
camera.startPreview();
}
}
};
}
Preview.java
public class Preview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
public Camera camera;
Preview(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
camera.setDisplayOrientation(90);
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Preview.this.invalidate();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
camera.startPreview();
}
}
edit: here’s the exception
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): FATAL EXCEPTION: main
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): java.lang.RuntimeException: Method called after release()
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at android.hardware.Camera.setHasPreviewCallback(Native Method)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at android.hardware.Camera.access$600(Camera.java:114)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at android.hardware.Camera$EventHandler.handleMessage(Camera.java:545)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at android.os.Handler.dispatchMessage(Handler.java:99)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at android.os.Looper.loop(Looper.java:143)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at android.app.ActivityThread.main(ActivityThread.java:4196)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at java.lang.reflect.Method.invokeNative(Native Method)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at java.lang.reflect.Method.invoke(Method.java:507)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-18 01:18:50.242: ERROR/AndroidRuntime(10222): at dalvik.system.NativeStart.main(Native Method)
Edit: Sorry, I take back the previous solution.
The problem is with the onPreviewFrame callback, why do you need it? Once you set the preview display you don’t need to invalidate the view, it is done automatically by the camera.