【发布时间】:2013-04-07 12:56:21
【问题描述】:
有没有办法检查相机是否打开?我不想打开相机,我只想检查它的状态。
【问题讨论】:
有没有办法检查相机是否打开?我不想打开相机,我只想检查它的状态。
【问题讨论】:
如果您的设备 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 和whole package
如果 API 级别低于 23,尝试打开摄像头检查是否抛出异常效果很好。在 API 级别 23 中,摄像头服务与以前不同,来自official docs:
根据客户端应用程序进程的“优先级”授予对摄像头子系统资源的访问权限,包括打开和配置摄像头设备。具有用户可见或前台活动的应用程序进程通常被赋予更高的优先级,从而使相机资源的获取和使用更加可靠。
当优先级较高的应用程序尝试使用相机时,较低优先级应用程序的活动相机客户端可能会被“驱逐”。在已弃用的 Camera API 中,这会导致为被驱逐的客户端调用 onError()。在 Camera2 API 中,它会为被驱逐的客户端调用 onDisconnected()。
我们可以看到,在 API 23 或更高版本中,尝试打开其他应用程序/进程使用的相机会从正在使用它的应用程序/进程中获取相机,而不是获取RuntimeException。
【讨论】:
您可以使用方法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 这意味着相机正在被另一个进程使用或设备策略管理器已禁用相机。
【讨论】:
查看the source code of Camera、its 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。
【讨论】: