如何检查摄像头是否被任何应用程序打开

19

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

3个回答

24
如果您的设备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.AvailabilityCallback整个包

如果API级别低于23,则尝试打开相机以检查是否引发异常效果良好。在API级别23中,相机服务与以前不同,详见官方文档:

基于客户端应用程序进程的“优先级”来授予对相机子系统资源(包括打开和配置相机设备)的访问权限。具有用户可见或前台活动的应用程序进程通常具有更高的优先级,使得相机资源获取和使用更加可靠。

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

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


12

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

创建一个新的 Camera 对象来访问特定的硬件摄像头。如果同一摄像头被其他应用程序打开,将引发 RuntimeException 异常。

抛出 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,则表示摄像头正在被另一个进程或设备策略管理器使用禁用了摄像头。


2
观察相机的源代码它的JNI对应部分和最终用于将相机与服务连接的本地代码,看起来唯一确定相机是否正在使用的方法是直接通过Camera::connect(jint)的结果。
问题在于,这个本地代码只能通过JNI函数android_hardware_Camera_native_setup(JNIEnv*, jobject, jobject, jint)访问,该函数在从Java中使用new Camera(int)创建相机实例时设置相机供使用。
简而言之,似乎不可能。您必须尝试打开相机,如果失败,则假定它正在被另一个应用程序使用。例如:
public boolean isCameraInUse() {
    Camera c = null;
    try {
        c = Camera.open();
    } catch (RuntimeException e) {
        return true;
    } finally {
        if (c != null) c.release();
    }
    return false;
}

为了更好地理解相机本地代码的基本流程,请查看此线程

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接