只能打开相机一次吗? [英] Can only open camera once?

查看:102
本文介绍了只能打开相机一次吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的拍照算法第一次成功运行,但是如果第二次调用该方法,则会得到 java.lang.RuntimeException:无法连接到相机服务 camera.open()

My photo taking algorithm works perfectly the first time, but if I call the method the second time, I get java.lang.RuntimeException: Fail to connect to camera service on 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) only 不管什么时候都可以首次使用。即使我切换了第二个参数,也只有第一个 takePhoto()有效。

It's odd, because takePhoto(context, int) only works the first time no matter what. Even if I switch the second parameter, only the first takePhoto() works.


我花了数小时的调试时间才意识到只有第二行是
的问题,但我对原因感到困惑。
非常感谢任何反馈!

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交互,因此我无法使线程休眠。

Even after removing the code in my onPictureTaken callback, the problem continues to persist. I suspect the camera may need time to reopen immediately, but I can't sleep the thread since I'm performing UI interactions on it. This bug is like a puzzle right now!

推荐答案

您无法调用 takePhoto()一个接一个,因为此调用需要很长时间(和两个回调)才能完成。第一张照片完成后,您应该开始第二个通话。这是一个基于您的代码的示例:

You cannot call takePhoto() one after another, because this call takes long time (and two callbacks) to complete. You should start the second call after the first picture is finished. Here is an example, based on your code:

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

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

This will start the first photo and start the second photo only when the first is complete.

这篇关于只能打开相机一次吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆