【问题标题】:Android Camera safe opening/closingAndroid相机安全打开/关闭
【发布时间】:2014-07-06 19:27:59
【问题描述】:

我已经阅读了有关在 Android 中安全打开/关闭摄像头的 Android 指南和堆栈问题,但我还没有找到答案。 这是我用于打开相机的代码 sn-p(在扩展 SurfaceView 的 CameraView 类中):

@Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) {
                this.camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            } else {
                this.camera = Camera.open();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace(System.out);
        }
    }

我正在检查 BUILD_SDK,因为例如在 Nexus7 上 camera.open() 不起作用 - 我必须使用 camera.open(0) - 但 camera.open(int) 在 SDK 8 中不可用。这里是我的关闭相机 sn-p:

@Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();
    }

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

当与我的 CameraView 连接的活动进入 onPause 状态时,我也在使用 releaseCamera() 函数。 这段代码在大多数设备上都可以正常工作(我已经在 Galaxy GIO、LG 4X HD 和 Galaxy S2 上检查过)但是我发布了一个带有这个代码 sn-p 的应用程序,用户仍然报告连接到相机的崩溃,这里是他们的 logcat:

java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.native_setup(Native Method)
at android.hardware.Camera.<init>(Camera.java:423)
at android.hardware.Camera.open(Camera.java:384)
at com.artostolab.xray.CameraView.surfaceCreated(CameraView.java:101)
at android.view.SurfaceView.updateWindow(SurfaceView.java:606)
at android.view.SurfaceView.access$000(SurfaceView.java:88)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:183)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:692)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2123)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1139)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4879)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
at android.view.Choreographer.doCallbacks(Choreographer.java:579)
at android.view.Choreographer.doFrame(Choreographer.java:548)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5297)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)

还有他们的设备: LG 擎天柱 G (geehrc4g) LG 擎天柱 L7 (u0)
IRIS504Q

你知道为什么会这样吗?提前致谢

21.01.2014 更新

我现在使用了一个功能来找回 CommonsWare 提出的相机,它工作正常,但是现在我从其他不那么流行的设备(Htc EVo 3D、城市生活、华为 U8815)的用户那里遇到了同样的错误。你知道什么可能导致这个问题吗?这是他们的日志(我更新了主要问题)-

java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.native_setup(Native Method)
at android.hardware.Camera.<init>(Camera.java:300)
at android.hardware.Camera.open(Camera.java:253)
at com.artostolab.xray.CameraView.surfaceCreated(CameraView.java:105)
at android.view.SurfaceView.updateWindow(SurfaceView.java:552)
at android.view.SurfaceView.dispatchDraw(SurfaceView.java:350)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.View.draw(View.java:6892)
at android.widget.FrameLayout.draw(FrameLayout.java:357)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1884)
at android.view.ViewRoot.draw(ViewRoot.java:1524)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1260)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1864)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
at dalvik.system.NativeStart.main(Native Method)

我的功能是找到合适的相机

public int findBackCamera() {
        int cameraId = -1;
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

【问题讨论】:

  • 为什么不打开一个新问题?它不需要额外的钱,但更容易理解和回答。 FWIW,您的新代码不会检查是否存在后置摄像头,使用 cameraId==-1 会使您的应用崩溃。

标签: android camera android-camera


【解决方案1】:

这是我打开相机的代码sn-p

该代码不正确。 open() 获取相机的 ID,而不是 CAMERA_FACING_BACK

【讨论】:

  • CAMERA_FACING_BACK 不返回整数值吗?
  • 是的,Camera.CameraInfo.CAMERA_FACING_BACK 返回 0 - 这是一个常量
  • @Saqib:Random.nextInt() 也是如此。 open() 也不能使用随机数。请遍历相机并通过其CameraInfofacing 设置为CAMERA_FACING_BACK 找到相机。请参阅this tutorial 中的findFrontFacingCamera() 方法,并将其修改为使用后置摄像头而不是前置摄像头。
  • @CommonsWare:感谢您的解释,但是如果我们确定这件事怎么办,比如暂时确定我的设备中有两个摄像头。另外我有类似的问题只发生在 Nexus 3
  • @Saqib:“就目前而言,我的设备中肯定有两个摄像头”——你仍然不知道你想要摄像头 ID 0 还是 1。您需要遍历可用的相机以找到具有您想要的特征的相机(在这种情况下,facing 设置为CAMERA_FACING_BACK)。据我所知,从来没有“Nexus 3”设备。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多