CameraManager
1、概述
CameraManager 是一个负责查询和建立相机连接的系统服务,关键功能:
- 将相机信息封装到 CameraCharacteristics 中,并提获取 CameraCharacteristics 实例的方式。
- 根据指定的相机 ID 连接相机设备。
- 提供将闪光灯设置成手电筒模式的快捷方式。
2、获取实例
通过 Context
类的 getSystemService()
方法来获取一个系统服务
1 | CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); |
3、内部类
CameraManager.AvailabilityCallback
相机设备的可用状态发生变化时,触发回调。
- public void onCameraAvailable(@NonNull String cameraId)
- public void onCameraUnavailable(@NonNull String cameraId)
String cameraId 相机设备的唯一标识。
CameraManager.TorchCallback
闪光灯的可用状态发生变化时触发回调。
- public void onTorchModeUnavailable(@NonNull String cameraId)
- public void onTorchModeChanged(@NonNull String cameraId, boolean enabled)
- String cameraId 相机设备的唯一标识。
- boolean enabled 闪光灯变化前的状态
CameraManager.CameraManagerGlobal
全局Camera管理实例,单例,保持一个与camera service得连接,同时分发API注册得可用回调。
4、主要接口
获取Camera设备列表
1 |
|
注册可用状态变化回调
注册一个回调用来当可用状态变化的时候,进行通知。
- 注册一个相同的回调,那么新的会替代旧的。
- 第一次注册回调时,立刻激活一次回调,回报当前可用的camera设备;
- 不管什么时候调用了camera被打开了都会触发回调;
- 如果没有必要时,记得注销回调。不然会占用资源。 回调将独立于一般Activity的生命周期,独立调用CameraManger。
- 支持再给定的Handle或Executor 上触发回调;
支持的接口
1 | public void registerAvailabilityCallback(@NonNull AvailabilityCallback callback, |
@NonNull AvailabilityCallback callback 新的回调
@Nullable Handler handler 在之上会调用callback,如果设置为null,则使用当前线程(android.os.Looper looper);
1 | public void registerAvailabilityCallback(@NonNull @CallbackExecutor Executor executor, |
- @NonNull @CallbackExecutor Executor executor, 在之上调用callback。
- @NonNull AvailabilityCallback callback 新的回调。
注销可用状态回调
移除之前注册的回调,此callback 不会再接收连接和断开的事件。
1 | public void unregisterAvailabilityCallback(@NonNull AvailabilityCallback callback) { |
注册闪光灯回调
注册回调用于关注闪光灯状态
注册一个相同的回调,那么新的会替代旧的。
第一次注册时,会立刻回调具备闪光灯单元的所有Camera设备。
注册此回调到camera service后,记得不需要的时候注销此回调,不然一旦闪光灯状态变化会触发回调,影响相应资源释放。回调将独立于一般Activity的生命周期,独立调用CameraManger。
支持再给定的Handle或Executor 上触发回调。
支持的接口
1 | public void registerTorchCallback(@NonNull TorchCallback callback, @Nullable Handler handler) { |
@NonNull TorchCallback callback 新的回调
@Nullable Handler handler 在之上会调用callback,如果设置为null,则使用当前线程(android.os.Looper looper);
1 | public void registerTorchCallback(@NonNull @CallbackExecutor Executor executor, |
- @NonNull @CallbackExecutor Executor executor, 在之上调用callback。
- @NonNull TorchCallback callback 新的回调。
注销闪光灯回调
移除之前注册的回调,此callback 不会再接收闪光灯状态变化的事件。
1 | public void unregisterTorchCallback(@NonNull TorchCallback callback) { |
获取Camera特性
查询并获取指定Camera的特性和能力,这些特性是不可修改的。
- 从API 29 开始,此接口也可用于查询物理摄像头的特性,物理摄像头仅可以是逻辑复合摄像头的一部分,不能直接被openCamera接口打开。
1 |
|
- @NonNull String cameraId 可以是一个独立的camera 或者仅是一个物理摄像头。
打开Camera
建立一个到给定Camera的连接。
- 及时打开的是使用 getCameraIdList 获取的cameraId指定的Camera 也可能操作失败,因为Camera有可能已经断开连接或者被其他更高级别的API打开而被占用。
- 即使低优先级的client已经打开了Camera,高优先级的client也可以成功打开Camera,此时低级别的Client会收到回调事件android.hardware.camera2.CameraDevice.StateCallback#onDisconnected。如果你的client处于 顶层或者前台的Activity 那么你的client可以获得更高的优先级。
- 一旦成功打开Camera,会触发回调 CameraDevice.StateCallback#onOpened,那么你就可以使用Camera的相关操作,比如发起拍照请求等。
- 如果在初始化期间Camera断开,那么会有一个CameraDevice.StateCallback#onDisconnected回调其中带有Camera状态,回调CameraDevice.StateCallback#onOpened就会被跳过。
- 如果打开Camera失败,会触发回调CameraDevice.StateCallback#onError onError,随后在这个Camera上的调用就会抛出异常CameraAccessException。
支持的接口
1 | (android.Manifest.permission.CAMERA) |
- @NonNull String cameraId: camera 唯一标识
- CameraDevice.StateCallback callback CameraDevice状态回调
- @Nullable Handler handler 在其上运行回调。
1 | (android.Manifest.permission.CAMERA) |
- @NonNull String cameraId: camera 唯一标识
- @NonNull @CallbackExecutor Executor executor CameraDevice状态回调
- @Nullable Handler handler 在其上运行回调。
1 | public void openCameraForUid(@NonNull String cameraId, |
此接口为隐藏接口
int clientUid UID为clientUid 的应用将打开Camera,一般设置为USE_CALLING_UID,除非是可信任的服务。
设置闪光灯模式
设置指定camera得闪光灯模式,不需要打开camera。
使用getCameraIdList获取可用Camera列表,使用getCameraCharacteristics查看Camera是否包含闪光灯。即使Camera包含闪光灯,也有可能打开闪光灯失败,因为或许在使用中。
setTorchMode调用成功,CameraManager.TorchCallback#onTorchModeChanged会触发。即使打开了闪光灯,应用也不是独占闪光灯或者Camera。如果最后一个打开闪光灯得应用退出了,闪光灯将关闭。
1 | public void setTorchMode(@NonNull String cameraId, boolean enabled) |
5、核心实现
相关代码位于源码位置:
1 | frameworks\base\core\java\android\hardware\camera2\CameraManager.java |
Application framework:用于给APP提供访问hardware的Camera API2,通过binder来访问camera service。
AIDL: 基于Binder实现的一个用于让App framework代码访问natice 代码的接口。其实现存在于下述路径:frameworks/av/camera/aidl/android/hardware。其中:
- ICameraService 是相机服务的接口。用于请求连接、添加监听等。
- ICameraDeviceUser 是已打开的特定相机设备的接口。应用框架可通过它访问具体设备。
- ICameraServiceListener 和 ICameraDeviceCallbacks 分别是从 CameraService 和 CameraDevice 到应用框架的回调。
Natice framework:frameworks/av/。提供了ICameraService、ICameraDeviceUser、ICameraDeviceCallbacks、ICameraServiceListener等aidl接口的实现。以及camera server的main函数。
Binder IPC interface:提供进程间通信的接口,APP和CameraService的通信、CameraService和HAL的通信。其中,AIDL、HIDL都是基于Binder实现的。
Camera Service:frameworks/av/services/camera/。同APP、HAL交互的服务,起到了承上启下的作用。
HAL:Google的HAL定义了可以让Camera Service访问的标准接口。对于供应商而言,必须要实现这些接口。
查看CameraManager类,其主要功能由其内部类 CameraManagerGlobal 代理实现。CameraManagerGlobal 是一个单例,CameraManagerGlobal 是真正的实现层,它与 CameraService 创建连接,从而创建相机的连路。