15、相机与传感器兼容性:CameraX与Camera2 API的升级路径,传感器权限变更。
相机和传感器,一直是Android系统升级中最让人头疼的部分。我做了这么多年系统兼容性,可以说,每次大版本升级,相机这块总能冒出些新问题。今天咱们就聊聊CameraX和Camera2的升级路径,以及传感器权限那些事儿。
一、Camera2 API:老将的坚守与挑战
Camera2是Android 5.0引入的框架层API。说实话,它功能很强大,但用起来也真够复杂的。我记得刚接触那会儿,光一个预览流程就要写上百行代码。
Camera2的核心架构是这样的:
// Camera2的基本使用流程
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
// 配置输出流
StreamConfigurationMap configMap = characteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] outputSizes = configMap.getOutputSizes(ImageFormat.JPEG);
// 创建CaptureSession
cameraDevice.createCaptureSession(outputSurfaces,
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
// 开始预览
session.setRepeatingRequest(previewRequest,
new CameraCaptureSession.CaptureCallback() {
// 处理回调
}, backgroundHandler);
}
}, backgroundHandler);
升级到Android 12以后,Camera2有几个关键变化:
- 会话参数API:可以在不重建session的情况下动态调整参数
- 扩展模式:支持HDR、夜景等高级功能
- 并发相机:同时打开多个摄像头
注意:Android 14开始,Camera2的某些旧接口被标记为deprecated。如果你还在用老代码,建议尽快迁移到新API。
二、CameraX:Google力推的新选择
CameraX是Jetpack家族的一员。说白了,它是对Camera2的封装,让开发者用起来更省心。我个人习惯在新项目里直接用CameraX,除非有特殊需求。
CameraX的优势很明显:
- 生命周期感知:自动处理Activity/Fragment的生命周期
- 用例驱动:预览、拍照、分析,三个用例搞定大部分场景
- 设备兼容性:Google做了大量设备适配工作
// CameraX的基本使用 - 简洁多了
val preview = Preview.Builder().build()
val imageCapture = ImageCapture.Builder().build()
val imageAnalyzer = ImageAnalysis.Builder().build()
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture, imageAnalyzer
)
} catch (e: Exception) {
Log.e(TAG, "绑定失败", e)
}
}, ContextCompat.getMainExecutor(this))
我的建议:如果你的应用需要支持Android 5.0以下设备,或者需要非常底层的相机控制,用Camera2。其他情况,优先考虑CameraX。
三、升级路径:从Camera2到CameraX
很多老项目用的是Camera2,现在想迁移到CameraX。嗯,这里要注意,不是简单的替换,需要重新设计架构。
我总结了一个迁移路线图:
- 评估需求:列出所有相机功能,看看CameraX是否都支持
- 分层改造:先抽象出相机接口,再逐步替换实现
- 测试覆盖:不同设备、不同Android版本都要测
为什么会这样?因为CameraX和Camera2的设计理念完全不同。Camera2是面向过程的,CameraX是面向用例的。你想想看,原来你写了一大堆状态机管理,现在只需要声明几个用例就行了。
核心要点:迁移不是重写,而是重构。保持接口不变,逐步替换内部实现。
四、传感器权限变更:Android 13/14的新规
传感器权限这块,Android 13开始有了重大变化。以前应用可以随便访问传感器数据,现在不行了。
具体来说:
| Android版本 | 传感器权限变化 |
|---|---|
| Android 12及以下 | 不需要运行时权限,直接访问 |
| Android 13 | 新增BODY_SENSORS_BACKGROUND权限 |
| Android 14 | 限制后台传感器访问,新增前台服务类型 |
我在项目中遇到过一个问题:某个健康类应用,在Android 14上突然获取不到心率数据了。查了半天,原来是后台传感器访问被限制了。
避坑指南:我曾经因为没处理传感器权限变更,导致应用在Android 14上崩溃。记住,一定要在运行时检查权限,并且处理权限被拒绝的情况。
权限声明示例:
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.BODY_SENSORS" />
<!-- Android 13+ 后台传感器权限 -->
<uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" />
<!-- 前台服务类型声明 -->
<service
android:name=".SensorService"
android:foregroundServiceType="sensors"
android:exported="false" />
五、知识体系总览
说了这么多,咱们用一张图来梳理一下整个知识体系:
这张图把整个知识体系分成了三大块。左边是Camera2,右边是CameraX,下面是传感器权限。三者之间既有联系,又有区别。
个人经验:我建议你在做系统升级时,先画一张类似的图,把当前项目用到的API和权限都列出来。这样升级的时候,哪里需要改,一目了然。
好了,关于相机和传感器的兼容性,今天就聊到这儿。记住,技术选型没有绝对的对错,关键是要适合你的项目场景。