Android 在发布异常摄影机预览后调用的方法
我有一个活动类(CameraActivity),它使用我的CameraPreview类。在“OnResume”中,启动相机和预览。在“OnPause”中,我正在释放相机资源。当应用程序启动时,“OnResume”内的一切正常,但当我通过intent(例如,在浏览器中打开url)启动另一个活动,然后返回到我的活动时,“OnResume”原始CamerView类内发生异常。请查看以下代码: //CameraActivity类Android 在发布异常摄影机预览后调用的方法,android,camera,Android,Camera,我有一个活动类(CameraActivity),它使用我的CameraPreview类。在“OnResume”中,启动相机和预览。在“OnPause”中,我正在释放相机资源。当应用程序启动时,“OnResume”内的一切正常,但当我通过intent(例如,在浏览器中打开url)启动另一个活动,然后返回到我的活动时,“OnResume”原始CamerView类内发生异常。请查看以下代码: //CameraActivity类 public void onResume(){ super.onR
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;
}
//下面是CameraPreview类:
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());
}
}
}
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)
boolean cameraReleased = false;
@Override
protected void onPause() {
Log.i("onPause", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == false) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.stopCamera();
cameraReleased = true;
}
if (cameraView == null) {
Log.i("onPause", "cameraView == null");
cameraView = new JJCameraSurfaceView(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onPause();
}
@Override
protected void onDestroy() {
Log.e("onDestroy", "INITIATED");
super.onDestroy();
}
@Override
protected void onResume() {
Log.i("onResume", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == true) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
}
if (cameraView == null) {
Log.i("onResume", "cameraView == null");
cameraView = new JJCameraPreview(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onResume();
}
@Override
public void onBackPressed() {
// If Statement used to get out of my camera view and back to my MainActivity - Same Class
if (“Camera Preview or Image Result is displayed”) {
cameraView.stopCamera();
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
return;
}
Log.i("onBackPressed", "WAS PRESSED");
super.onBackPressed();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.w("surfaceChanged", "STARTED");
if (camera != null) {
Log.w("surfaceChanged", "camera = NOT NULL");
Camera.Parameters cParams = camera.getParameters();
cParams.setPreviewSize(width, height);
cParams.setSceneMode(Parameters.SCENE_MODE_NIGHT);
camera.setParameters(cParams);
camera.startPreview();
}
}
public void surfaceCreated(SurfaceHolder holder) {
Log.w("surfaceCreated", "STARTED");
if (camera == null) {
camera = Camera.open();
}
try {
camera.setPreviewDisplay(mHolder);
} catch (Exception e) {
Log.e("setPreviewDisplay", "FAILED: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.w("CameraSurfaceDestroyed", "INITIATED");
camera.stopPreview();
camera.release();
camera = null;
}
public void startCamera() {
Log.w("startCamera", "CALLED");
mHolder = getHolder();
surfaceCreated(mHolder);
camera.startPreview();
mHolder.addCallback(this);
}
public void stopCamera() {
mHolder = getHolder();
mHolder.removeCallback(this);
camera.stopPreview();
}
这是来自logCat:
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());
}
}
}
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)
boolean cameraReleased = false;
@Override
protected void onPause() {
Log.i("onPause", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == false) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.stopCamera();
cameraReleased = true;
}
if (cameraView == null) {
Log.i("onPause", "cameraView == null");
cameraView = new JJCameraSurfaceView(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onPause();
}
@Override
protected void onDestroy() {
Log.e("onDestroy", "INITIATED");
super.onDestroy();
}
@Override
protected void onResume() {
Log.i("onResume", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == true) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
}
if (cameraView == null) {
Log.i("onResume", "cameraView == null");
cameraView = new JJCameraPreview(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onResume();
}
@Override
public void onBackPressed() {
// If Statement used to get out of my camera view and back to my MainActivity - Same Class
if (“Camera Preview or Image Result is displayed”) {
cameraView.stopCamera();
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
return;
}
Log.i("onBackPressed", "WAS PRESSED");
super.onBackPressed();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.w("surfaceChanged", "STARTED");
if (camera != null) {
Log.w("surfaceChanged", "camera = NOT NULL");
Camera.Parameters cParams = camera.getParameters();
cParams.setPreviewSize(width, height);
cParams.setSceneMode(Parameters.SCENE_MODE_NIGHT);
camera.setParameters(cParams);
camera.startPreview();
}
}
public void surfaceCreated(SurfaceHolder holder) {
Log.w("surfaceCreated", "STARTED");
if (camera == null) {
camera = Camera.open();
}
try {
camera.setPreviewDisplay(mHolder);
} catch (Exception e) {
Log.e("setPreviewDisplay", "FAILED: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.w("CameraSurfaceDestroyed", "INITIATED");
camera.stopPreview();
camera.release();
camera = null;
}
public void startCamera() {
Log.w("startCamera", "CALLED");
mHolder = getHolder();
surfaceCreated(mHolder);
camera.startPreview();
mHolder.addCallback(this);
}
public void stopCamera() {
mHolder = getHolder();
mHolder.removeCallback(this);
camera.stopPreview();
}
编辑
我更新了“surfaceDestroyed”并按建议放置日志,但现在我在“onPause”-->onSurfaceDestroyed中遇到异常。起初,onPause执行得很好
1-摄影机实例通过方法“GetCameranStance”在活动类的“onResume”中创建,并将mCamera实例传递给CameraPreview类。我试图更改它,以便只在“onSurfaceCreated”一侧创建camera实例,并将mCamera实例分配回activity类,但它不起作用。我还通过调试注意到,“CameraPreview”类的previewCallBack成员第一次有效,但第二次“CameraPreview”类的“previewCallBack”成员为空
请注意,第一次调用“onResume”时,一切正常,但当它在onPause之后第二次运行时,最初会发生异常,尽管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)
编辑
这是一个很难回答的问题,我现在无法100%确定是什么导致了您的异常。我已经在下面包含了我的相机代码,希望这会有所帮助,我使用了startCamera()
和stopCamera()
方法,在onPause
和onResume
中调用这些方法。另外,我只在我的onCreate
中创建CameraPreview
类的新实例,我不会在onResume
中重新实例化,除非我的cameraView==null
。有两件事我们做得不同。希望下面的代码会有所帮助,也许您可以使用它来让您的工作正常:
附言:一切都对我有用。i、 e.进入其他活动等。生命周期中我唯一没有测试的部分是onDestroy
,但这是因为我的应用程序设计为在这个周期的开始时启动
main活动:
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());
}
}
}
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)
boolean cameraReleased = false;
@Override
protected void onPause() {
Log.i("onPause", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == false) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.stopCamera();
cameraReleased = true;
}
if (cameraView == null) {
Log.i("onPause", "cameraView == null");
cameraView = new JJCameraSurfaceView(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onPause();
}
@Override
protected void onDestroy() {
Log.e("onDestroy", "INITIATED");
super.onDestroy();
}
@Override
protected void onResume() {
Log.i("onResume", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == true) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
}
if (cameraView == null) {
Log.i("onResume", "cameraView == null");
cameraView = new JJCameraPreview(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onResume();
}
@Override
public void onBackPressed() {
// If Statement used to get out of my camera view and back to my MainActivity - Same Class
if (“Camera Preview or Image Result is displayed”) {
cameraView.stopCamera();
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
return;
}
Log.i("onBackPressed", "WAS PRESSED");
super.onBackPressed();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.w("surfaceChanged", "STARTED");
if (camera != null) {
Log.w("surfaceChanged", "camera = NOT NULL");
Camera.Parameters cParams = camera.getParameters();
cParams.setPreviewSize(width, height);
cParams.setSceneMode(Parameters.SCENE_MODE_NIGHT);
camera.setParameters(cParams);
camera.startPreview();
}
}
public void surfaceCreated(SurfaceHolder holder) {
Log.w("surfaceCreated", "STARTED");
if (camera == null) {
camera = Camera.open();
}
try {
camera.setPreviewDisplay(mHolder);
} catch (Exception e) {
Log.e("setPreviewDisplay", "FAILED: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.w("CameraSurfaceDestroyed", "INITIATED");
camera.stopPreview();
camera.release();
camera = null;
}
public void startCamera() {
Log.w("startCamera", "CALLED");
mHolder = getHolder();
surfaceCreated(mHolder);
camera.startPreview();
mHolder.addCallback(this);
}
public void stopCamera() {
mHolder = getHolder();
mHolder.removeCallback(this);
camera.stopPreview();
}
CameraPreview:
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());
}
}
}
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)
boolean cameraReleased = false;
@Override
protected void onPause() {
Log.i("onPause", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == false) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.stopCamera();
cameraReleased = true;
}
if (cameraView == null) {
Log.i("onPause", "cameraView == null");
cameraView = new JJCameraSurfaceView(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onPause();
}
@Override
protected void onDestroy() {
Log.e("onDestroy", "INITIATED");
super.onDestroy();
}
@Override
protected void onResume() {
Log.i("onResume", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == true) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
}
if (cameraView == null) {
Log.i("onResume", "cameraView == null");
cameraView = new JJCameraPreview(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onResume();
}
@Override
public void onBackPressed() {
// If Statement used to get out of my camera view and back to my MainActivity - Same Class
if (“Camera Preview or Image Result is displayed”) {
cameraView.stopCamera();
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
return;
}
Log.i("onBackPressed", "WAS PRESSED");
super.onBackPressed();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.w("surfaceChanged", "STARTED");
if (camera != null) {
Log.w("surfaceChanged", "camera = NOT NULL");
Camera.Parameters cParams = camera.getParameters();
cParams.setPreviewSize(width, height);
cParams.setSceneMode(Parameters.SCENE_MODE_NIGHT);
camera.setParameters(cParams);
camera.startPreview();
}
}
public void surfaceCreated(SurfaceHolder holder) {
Log.w("surfaceCreated", "STARTED");
if (camera == null) {
camera = Camera.open();
}
try {
camera.setPreviewDisplay(mHolder);
} catch (Exception e) {
Log.e("setPreviewDisplay", "FAILED: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.w("CameraSurfaceDestroyed", "INITIATED");
camera.stopPreview();
camera.release();
camera = null;
}
public void startCamera() {
Log.w("startCamera", "CALLED");
mHolder = getHolder();
surfaceCreated(mHolder);
camera.startPreview();
mHolder.addCallback(this);
}
public void stopCamera() {
mHolder = getHolder();
mHolder.removeCallback(this);
camera.stopPreview();
}
我的代码也有类似的问题,那就是使用release()后调用的
方法强制关闭错误
我正在调用OnResume()
中的SetupCamera()
方法,该方法检查空camera
对象,然后调用camera.Open()
解决我的问题的方法是,去掉空检查,在阅读后只需调用camera.Open()
它是否为空(我已经在onPause
上设置了camera=null
)
我知道这在追踪我的问题时不是决定性的,但它对我绝对有效 将相机添加到FrameLayout后,如下所示:
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
preview.removeView(mPreview);
public CameraPreview(Context context, Camera[] camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
mCamera = camera;
...
}
将调用surfaceCreated
方法,因此mCamera.setPreviewDisplay(holder)代码>将被调用
创建/打开新相机时,FrameLayout
仍保留您以前的相机,因此除了新相机外,还将调用其surfaceCreated
当您松开相机时(在onPause()
方法上),您应该做的是从FrameLayout
中移除以前的相机,如下所示:
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
preview.removeView(mPreview);
public CameraPreview(Context context, Camera[] camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
mCamera = camera;
...
}
希望有帮助。丹是对的。另见
代码示例:
public class MainActivity extends Activity {
private FrameLayout mFlCameraPreview;
private Camera mCamera;
private CameraPreview mCameraPreview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFlCameraPreview = (FrameLayout) findViewById(R.id.main_fl_camera_preview);
}
@Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
mCamera = getCameraInstance();
}
if (mCameraPreview == null) {
mCameraPreview = new CameraPreview(this, mCamera);
mFlCameraPreview.addView(mCameraPreview);
}
}
@Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if (mCameraPreview != null) {
mFlCameraPreview.removeView(mCameraPreview);
mCameraPreview = null;
}
}
public static Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
}
return camera;
}
}
我的工作解决方案:
第一:
在CameraActivity
类中,将mCamera
声明为数组:
Camera mCamera[] = new Camera[1];
第二:构造函数的声明CameraPreview
必须如下所示:
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
preview.removeView(mPreview);
public CameraPreview(Context context, Camera[] camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
mCamera = camera;
...
}
但是CameraPreview
类中的mCamera
必须声明如下:
Camera[] mCamera; // without instantiating of the array!
最后:在所有方法中的两个类中,您应该将所有引用mCamera
替换为mCamera[0]
注意:对不起,我的英语不好请尝试下面的代码,不要覆盖onPause()和onResume(),而要覆盖onStop()和onRestart()。在活动生命周期中,当活动不可见时调用onStop(),下一个生命周期方法调用将是onRestart()。看看下面的代码
@Override
protected void onStop() {
super.onStop();
try {
m_camera.stopPreview();
m_camera.release();
preview.removeView(m_CameraPreview);
/*
m_CameraPreview is the object of the class that looks like this : public class CameraSurfaceView extends SurfaceView implements Callback
*/
}
catch(Exception e)
{
e.printStackTrace();
}
}
@Override
protected void onRestart() {
super.onRestart();
m_camera=getCameraInstance();//Initialize the camera in your own way
m_CameraPreview = new CameraSurfaceView(this, m_camera);
preview = (FrameLayout)findViewById(R.id.camera_preview);
preview.addView(this.m_CameraPreview);
/*
*camera_preview is the id of the framelayout defined in xml file and preview is *the instance of FrameLayout.
*/
}
正如Dan所说,帧布局将保留以前的摄影机实例,其“surfaceview”回调将在创建竞争条件的新对象之外创建。因此,您需要在onStop()中释放它,并在onRestart()中重新初始化。
希望这有帮助。我也遇到了同样的错误。下面的顺序解决了我的问题
调用getHolder()代码>在surfaceDestroyed()中
召唤
在onPause中
召唤
在onCreateView()
中,我觉得您的相机似乎已被正确释放,但在恢复时它不会打开。在surfaceDestroyed
中,将mCamera
设置为null
,使其通过if(mCamera==null){
station insurfaceCreated
请将下面的一个标记为已接受,它解决了我的问题。@arunsoorya哪个答案?@ImranTariq答案多数赞成。我也遇到了同样的问题,我使用mCamera修复了它,它应该为null,因为CameraPreview是一个新创建的实例(因为它在onPaused中为null)嗯,您的相机没有被正确地重新打开。我最近遇到了问题,必须覆盖所有活动生命周期,以找出调用的活动,并确保我已正确地释放和重新打开。如果onPause
和onResume
与您的相机正常工作,那么当您U