【问题标题】:How to check if camera is opened by any application如何检查相机是否被任何应用程序打开
【发布时间】:2013-04-07 12:56:21
【问题描述】:

有没有办法检查相机是否打开?我不想打开相机,我只想检查它的状态

【问题讨论】:

    标签: android camera


    【解决方案1】:

    如果您的设备 API 版本高于 21,CameraManager.AvailabilityCallback 可能是一个不错的选择。

    需要先获取系统的摄像头管理器,代码如下:

    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    

    然后,您需要注册AvailabilityCallback

    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        manager.registerAvailabilityCallback(new CameraManager.AvailabilityCallback() {
            @Override
            public void onCameraAvailable(String cameraId) {
                super.onCameraAvailable(cameraId);
                //Do your work
            }
    
            @Override
            public void onCameraUnavailable(String cameraId) {
                super.onCameraUnavailable(cameraId);
                //Do your work
            }
        }, yourHandler);
    }
    

    如果 API 版本高于 21 则效果更好。您可以参考CameraManagerCameraManager.AvailabilityCallbackwhole package

    如果 API 级别低于 23,尝试打开摄像头检查是否抛出异常效果很好。在 API 级别 23 中,摄像头服务与以前不同,来自official docs

    根据客户端应用程序进程的“优先级”授予对摄像头子系统资源的访问权限,包括打开和配置摄像头设备。具有用户可见或前台活动的应用程序进程通常被赋予更高的优先级,从而使相机资源的获取和使用更加可靠。

    当优先级较高的应用程序尝试使用相机时,较低优先级应用程序的活动相机客户端可能会被“驱逐”。在已弃用的 Camera API 中,这会导致为被驱逐的客户端调用 onError()。在 Camera2 API 中,它会为被驱逐的客户端调用 onDisconnected()。

    我们可以看到,在 API 23 或更高版本中,尝试打开其他应用程序/进程使用的相机会从正在使用它的应用程序/进程中获取相机,而不是获取RuntimeException

    【讨论】:

      【解决方案2】:

      您可以使用方法Camera.open(cameraId)进行检查。

      创建一个新的相机对象来访问特定的硬件相机。如果同一个相机被其他应用程序打开,这将抛出一个 RuntimeException。

      投掷 运行时异常
      如果打开摄像头失败(例如,如果摄像头正在被另一个进程使用或设备策略管理器已禁用摄像头)。

      更新:

      例子:

      public boolean isCameraUsebyApp() {
          Camera camera = null;
          try {
              camera = Camera.open();
          } catch (RuntimeException e) {
              return true;
          } finally {
              if (camera != null) camera.release();
          }
          return false;
      }
      

      您可以按照 Paul 的建议使用此方法,但请记住,此方法首先获取相机。

      如果获取成功,则表示没有其他应用程序在使用此相机,不要忘记再次释放它,否则您将无法再次获取它。

      它抛出RuntimeException 这意味着相机正在被另一个进程使用或设备策略管理器已禁用相机。

      【讨论】:

        【解决方案3】:

        查看the source code of Cameraits JNI counterpart,最后查看the native code 以将摄像头与服务连接起来,看来确定摄像头是否正在使用的唯一方法是直接通过Camera::connect(jint) 的结果。

        问题在于,这个本机代码只能通过 JNI 函数android_hardware_Camera_native_setup(JNIEnv*, jobject, jobject, jint) 访问,该函数设置相机以供在new Camera(int) 中从 Java 中创建 Camera 实例时使用。

        简而言之,这似乎是不可能的。您必须尝试打开相机,如果失败,则假设它正在被另一个应用程序使用。例如:

        public boolean isCameraInUse() {
            Camera c = null;
            try {
                c = Camera.open();
            } catch (RuntimeException e) {
                return true;
            } finally {
                if (c != null) c.release();
            }
            return false;
        }
        

        为了更好地理解相机原生代码的底层流程,see this thread

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-08
          • 2010-11-06
          • 1970-01-01
          • 1970-01-01
          • 2022-06-14
          相关资源
          最近更新 更多