有什么方法可以检查相机是否打开?我不想打开相机,我只想检查它的状态。
3 回答
如果您的设备 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,这会更好。您可以参考CameraManager,CameraManager.AvailabilityCallback和整个包
如果 API 级别低于 23,尝试打开摄像头检查是否抛出异常效果很好。在 API 级别 23 中,摄像头服务与以前不同,来自官方文档:
根据客户端应用程序进程的“优先级”授予对摄像头子系统资源的访问权,包括打开和配置摄像头设备。具有用户可见或前台活动的应用程序进程通常被赋予更高的优先级,使相机资源的获取和使用更加可靠。
当较高优先级的应用程序尝试使用相机时,较低优先级应用程序的活动相机客户端可能会被“驱逐”。在已弃用的 Camera API 中,这会导致为被驱逐的客户端调用 onError()。在 Camera2 API 中,它会为被驱逐的客户端调用 onDisconnected()。
我们可以看到,在 API 23 或更高版本中,尝试打开其他应用程序/进程使用的摄像头会从正在使用它的应用程序/进程中获取摄像头,而不是获取RuntimeException
.
您可以使用方法检查它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
意味着相机正在被另一个进程使用或设备策略管理器已禁用相机。
查看Camera 的源代码,它的 JNI 对应物,最后是用于将相机与服务连接的本机代码,看来确定相机是否正在使用的唯一方法是直接通过Camera::connect(jint)
.
问题是这个本地代码只能通过 JNI 函数访问,该函数android_hardware_Camera_native_setup(JNIEnv*, jobject, jobject, jint)
设置相机以在从 Java 中创建 Camera 实例时使用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;
}
为了更好地理解相机本机代码的底层流程,请参阅此线程。