只能打开相机一次吗?

时间:2017-11-25 08:26:07

标签: java android algorithm performance android-camera

我的拍照算法第一次完美运行,但如果我第二次调用该方法,我会在java.lang.RuntimeException: Fail to connect to camera service上获得camera.open()

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()有效。

  

我花了几个小时的调试才意识到只有第二行   有问题,但我坚持为什么。任何反馈都很多   理解!

编辑:

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

2 个答案:

答案 0 :(得分:1)

您无法一个接一个地呼叫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");
    }
};

这将启动第一张照片并仅在第一张照片完成时开始第二张照片。

答案 1 :(得分:0)

这可能有问题。

拍完照片后,拍摄的回调会被调用。

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

    camera.release();
    camera = null;
}

相机已经发布,所以第二次没有工作。您必须再次打开相机或重新初始化相机才能拍照。