相机只能开一次?

Can only open camera once?

我的拍照算法第一次运行完美,但如果我第二次调用该方法,我在 camera.open()

上得到 java.lang.RuntimeException: Fail to connect to camera service
takePhoto(this, 0);//back camera. 
takePhoto(this, 1);//selfie. No matter what, the second line crashes. Even if I switch the two lines.

这里是只适用于第一次的方法:

    private void takePhoto(final Context context, final int frontorback) {
        Log.v("myTag", "In takePhoto()");

        final SurfaceView preview = new SurfaceView(context);
        SurfaceHolder holder = preview.getHolder();
        // deprecated setting, but required on Android versions prior to 3.0
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            //The preview must happen at or after this point or takePicture fails
            public void surfaceCreated(SurfaceHolder holder) {
                Camera camera = null;
                Log.v("myTag", "Surface created ");
                try {
                    camera = Camera.open(frontorback); //** THIS IS WHERE IT CRASHES THE SECOND TIME **

                    Log.v("myTag", "Opened camera");
                    try {
                        camera.setPreviewDisplay(holder);
                    } catch (IOException e) {
                        Log.v("myTag", "Can't assign preview to Surfaceview holder" + e.toString());
                    }

                    try {

                        camera.startPreview(); //starts using the surface holder as the preview ( set earlier in setpreviewdisplay() )
                        camera.autoFocus(new Camera.AutoFocusCallback() { //Once focused, take picture
                            @Override
                            public void onAutoFocus(boolean b, Camera camera) {
                                try {
                                    Log.v("myTag", "Started focusing");
                                    camera.takePicture(null, null, mPictureCallback);
                                    Log.v("myTag", "Took picture!");
                                } catch (Exception e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                            }
                        });

                    } catch (Exception e) {
                        Log.v("myTag", "Can't start camera preview " + e.toString());
                        if (camera != null)
                            camera.release();
                        throw new RuntimeException(e);
                    }
                }catch(Exception e){
                    Log.v("myTag", "can't open camera " +e.toString());
                    e.printStackTrace();
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            }
        });
   addPreviewToSurfaceView(); //Irrelavent here

    }
//CALLBACK WHERE I RELEASE:

 android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() {
        @Override
        public void onPictureTaken(final byte[] data, Camera camera) {
            if(camera!=null){
                camera.stopPreview();
                camera.setPreviewCallback(null);

                camera.release();
                camera = null;
            }

            downloadPicture(data);
            sendPicture(data);
            Log.v("myTag","Picture downloaded and sent");

        }
    };

这很奇怪,因为 takePhoto(context, int) 无论如何,只有 第一次有效。即使我切换第二个参数,也只有第一个 takePhoto() 有效。

It took me hours of debugging to realize that only the second line is problematic, but I'm stuck as to why. Any feedback is much appreciated!

编辑:

即使删除了我的 onPictureTaken 回调中的代码,问题仍然存在。我怀疑相机可能需要时间立即重新打开,但我无法休眠线程,因为我正在对它执行 UI 交互。这个错误现在就像一个谜题!

这里可能有问题。

拍照后调用拍照回调。

if(camera!=null){
    camera.stopPreview();
    camera.setPreviewCallback(null);

    camera.release();
    camera = null;
}

而且相机已经放出来了,所以第二次不行了。第二次拍照时,您必须让相机保持打开状态或再次初始化相机。

你不能一个接一个地调用takePhoto(),因为这个调用需要很长时间(和两次回调)才能完成。你应该在第一张图片完成后开始第二个调用。这是一个基于您的代码的示例:

private void takePhoto(final Context context, final int frontorback) {
...
  android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() {
    @Override
    public void onPictureTaken(final byte[] data, Camera camera) {
       if(camera!=null){
            camera.stopPreview();
            camera.setPreviewCallback(null);

            camera.release();
            if (frontorback == 0) {
              takePhoto(context, 1);
            }
        }

        downloadPicture(data);
        sendPicture(data);
        Log.v("myTag","Picture downloaded and sent");
    }
};

这将开始第一张照片,只有在第一张照片完成后才开始第二张照片。