Camera is null when the surfaceCreated method is e

2019-04-15 01:08发布

问题:

I have a problem with the camera object when the surfaceCreated method of a SurfaceHolder.Callback is called for second time, I mean:

I create an object camera in my onResume method from my activity, and this works fine showing the preview display, but when my activity goes to pause the surfaceview is destroyed and I have to release the camera object then if my activity comes to onresume android throws me a nullPointerException in my camera object.

I'm not sure why is happening this, I putted comments to debug every method and see what happens, apparently everything is fine only in the surfaceCreated method the camera object becomes to null.

This is my class:

public class CameraRecord implements SurfaceHolder.Callback{

public static final int BACK_CAMERA = 1;
public static final int FRONT_CAMERA = 2;
//private SurfaceView surface;
private SurfaceHolder holder;
private Camera camera;

public CameraRecord(SurfaceView surface){
//  this.surface = surface;
    holder = surface.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    Log.e("CameraRecord","constructor");
}


public void openCamera(int wichCamera) throws Exception {

    if (wichCamera == BACK_CAMERA)
        camera = Camera.open();
    else {
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        int cameraCount = Camera.getNumberOfCameras();

        for (int i = 0; i < cameraCount; i++ ) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
                try {
                    camera = Camera.open(i); 
                    Log.e("CameraRecord","camera is CAMERA_FACING_FRONT " + cameraInfo.toString());
                } catch (RuntimeException e) {
                    e.printStackTrace();
                }
        }
    }

    if (camera == null)
        Log.e("CameraRecord","openCamera camera is null");
    else
        Log.e("CameraRecord","openCamera camera is not null");

}

public void start() throws IOException {
    camera.startPreview();
}

public void stop() {
    camera.stopPreview();
    Log.e("CameraRecord","stop camera");
}

public void release() {
    camera.release();
    camera = null;
}




@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    Log.e("CameraRecord", "surfaceChanged");
    try {
        start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
//      if (holder == null)
//          Log.e("CameraRecord","holder is null");
//      else
//          Log.e("CameraRecord","holder is not null");

    try {
        if (camera == null)
            Log.e("CameraRecord","camera is null");
        else
            Log.e("CameraRecord","camera is not null");

        camera.setPreviewDisplay(holder);
//          start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    Log.e("CameraRecord", "surfaceDestroyed");
    stop();
    release();
}

}

回答1:

I was having this same problem. The way that I solved it was calling removeCallbak() method in my SurfaceHolder at the same time that I was releasing the camera (on the onPause() method). I guess that in your example would be

holder.removeCallback(this);

The idea is that not only you release the camera on the onPause() method of your activity, but also you remove the callback set on the SurfaceHolder. If you don't do this the error would appear the second time because the callbacks are being made to the first instance that you associated and not the second one. If you remove the callback also on onPause(), you shouldn't have any problems.



回答2:

I had problem like this , and after adding these 3 rows in the AndroidManifest.xml my app worked

<uses-permission android:name="android.permission.CAMERA" />    
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

maybe it'll help you :)



回答3:

public void release() {
    camera.release();
    camera = null;
}

this should be:

public void release() {
   if(camera!=null) camera.release();
    camera = null;
}