1

SurfaceHolder.Callback の surfaceCreated メソッドが 2 回目に呼び出されると、カメラ オブジェクトに問題があります。

アクティビティから onResume メソッドでオブジェクト カメラを作成すると、プレビュー表示が正常に表示されますが、アクティビティが一時停止すると、サーフェスビューが破棄され、カメラ オブジェクトを解放する必要があり、アクティビティが onresume android スローになると、カメラオブジェクトに nullPointerException が発生しました。

なぜこれが起こっているのかわかりません。コメントを付けてすべてのメソッドをデバッグし、何が起こるかを確認しました。明らかに、カメラ オブジェクトが null になる surfaceCreated メソッドでのみすべてが正常です。

これは私のクラスです:

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();
}

}

4

3 に答える 3

2

私はこれと同じ問題を抱えていました。私がそれを解決した方法は、(onPause() メソッドで) カメラを解放すると同時に、SurfaceHolder で removeCallbak() メソッドを呼び出すことでした。あなたの例では

holder.removeCallback(this);

アイデアは、アクティビティの onPause() メソッドでカメラを解放するだけでなく、SurfaceHolder に設定されたコールバックも削除することです。これを行わないと、2 番目のインスタンスではなく、関連付けた最初のインスタンスに対してコールバックが行われるため、エラーが 2 回目に表示されます。onPause() でコールバックを削除しても、問題はないはずです。

于 2013-06-01T23:27:38.220 に答える
0

このような問題があり、 AndroidManifest.xml にこれらの 3 行を追加した後、アプリが機能しました

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

多分それはあなたを助けるでしょう:)

于 2012-10-17T13:06:19.697 に答える
0
public void release() {
    camera.release();
    camera = null;
}

これは次のようになります。

public void release() {
   if(camera!=null) camera.release();
    camera = null;
}
于 2015-11-09T05:57:13.737 に答える