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。嗯,这里要注意,不是简单的替换,需要重新设计架构。

我总结了一个迁移路线图:

  1. 评估需求:列出所有相机功能,看看CameraX是否都支持
  2. 分层改造:先抽象出相机接口,再逐步替换实现
  3. 测试覆盖:不同设备、不同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 API • 底层控制能力强 • 代码复杂度高 • 需要手动管理状态 • 兼容性需自行处理 升级要点: • 会话参数API • 扩展模式支持 • 并发相机 ⚠ Android 14部分接口废弃 迁移 CameraX • 用例驱动设计 • 生命周期感知 • 设备兼容性好 • 代码简洁 核心用例: • Preview 预览 • ImageCapture 拍照 • ImageAnalysis 分析 ✅ 推荐新项目使用 传感器权限 • Android 13+ 新规 • BODY_SENSORS权限 • 后台访问限制 • 前台服务类型 版本变化: • Android 12: 直接访问 • Android 13: 后台权限 • Android 14: 前台服务 ⚠ 必须运行时检查 核心原则:根据场景选择API,关注权限变化,做好兼容性测试

这张图把整个知识体系分成了三大块。左边是Camera2,右边是CameraX,下面是传感器权限。三者之间既有联系,又有区别。

个人经验:我建议你在做系统升级时,先画一张类似的图,把当前项目用到的API和权限都列出来。这样升级的时候,哪里需要改,一目了然。

好了,关于相机和传感器的兼容性,今天就聊到这儿。记住,技术选型没有绝对的对错,关键是要适合你的项目场景。

公众号:蓝海资料掘金营,微信deep3321