8、应用开发基础:Car API 库(android.car.*),Car App 生命周期与权限管理

好,咱们今天聊聊车载应用开发的基础。说实话,Android Automotive OS 的应用开发和手机端有七分像,但剩下的三分,恰恰是坑最多的地方。我刚开始接触这个领域时,就拿着手机开发的惯性思维往上套,结果被 Car API 的权限模型狠狠教育了一回。

嗯,咱们一步步来。先搞清楚 Car API 库到底是什么,再说生命周期和权限。这些东西搞明白了,你写车载应用才算真正入了门。

8.1 Car API 库:android.car.* 的定位

Car API 库,说白了就是 Google 给车载场景单独开的小灶。它位于 android.car.* 包下,不是 AOSP 默认就有的,你得在编译时显式依赖它。

核心定位:Car API 是连接应用层和汽车硬件(CAN 总线、传感器、HAL 层)的桥梁。没有它,你的应用就是个普通 Android 应用,读不到车速、控制不了空调、也管不了方向盘按键。

我个人习惯把 Car API 分成三类:

  • 车辆硬件访问类:比如 CarSensorManager(车速、转速)、CarPropertyManager(空调、车门状态)。
  • 系统服务类:比如 CarParkingService(泊车辅助)、CarAudioManager(车载音频焦点)。
  • UI 组件类:比如 CarUiTextCarDrawable,专门适配车载大屏的交互规范。

你想想看,手机应用能随便调用 CarSensorManager 吗?不能。因为 Car API 的访问权限是受系统签名和角色控制的。这一点后面细说。

8.2 Car App 的生命周期:和手机有什么不同?

车载应用的生命周期,本质上还是基于 Android Activity 的生命周期。但有几个关键差异,我在项目中踩过坑,给你提个醒。

8.2.1 多窗口与分屏的常态

车载系统里,分屏是常态,不是特例。驾驶员侧看导航,副驾侧看视频,中间还可能有个 dock 栏。这意味着你的 Activity 随时可能进入 onMultiWindowModeChanged

我曾经遇到过一个音乐应用,在分屏模式下 onPause 被频繁触发,导致音乐播放中断。后来发现,车载系统对分屏的 onPause 行为做了定制——只有失去音频焦点时才算真正暂停

我的建议:在车载应用中,不要依赖 onPause 来做「停止播放」的逻辑。应该监听 CarAudioManager 的音频焦点变化,这才是车载场景下的正确姿势。

8.2.2 车载特有的「驾驶模式」生命周期

Android Automotive 引入了一个叫 DrivingState 的概念。当车辆处于行驶状态时,系统会限制某些应用的 UI 交互(比如禁止视频播放、限制列表滚动)。

这个状态变化是通过 CarDrivingStateManager 来监听的。代码大概长这样:

CarDrivingStateManager manager = car.getCarManager(CarDrivingStateManager.class);
manager.registerCallback(new CarDrivingStateEventCallback() {
    @Override
    public void onDrivingStateChanged(CarDrivingStateEvent event) {
        if (event.eventValue == CarDrivingStateEvent.DRIVING_STATE_MOVING) {
            // 车辆在行驶中,限制某些 UI 操作
            disableVideoPlayback();
        } else {
            // 停车或驻车状态,恢复功能
            enableVideoPlayback();
        }
    }
});

嗯,这里要注意:CarDrivingStateManager 需要 android.permission.READ_DRIVING_STATE 权限,而且这个权限是 signature|privileged 级别的。普通第三方应用拿不到。

8.3 权限管理:车载系统的「门禁系统」

车载系统的权限管理,比手机端严格得多。为什么?因为涉及安全。你想想看,一个恶意应用如果控制了刹车系统,那后果不堪设想。

Android Automotive 的权限体系分为三层:

权限级别 授予方式 典型权限
普通权限 安装时自动授予 ACCESS_NETWORK_STATE
危险权限 运行时弹窗申请 CAMERARECORD_AUDIO
车辆专属权限 系统签名 / 平台角色 CONTROL_CAR_CLIMATEREAD_VEHICLE_SPEED

这里重点说车辆专属权限。它们通常定义在 platform.xmlcar\_service\_permissions.xml 中。比如你想读取车速:

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.car.permission.CAR_SPEED" />

但光声明没用。这个权限是 signature 级别的,意味着只有和系统用同一签名密钥签名的应用才能获取。第三方应用?没戏。

避坑指南:我曾经在开发一个第三方导航应用时,想获取车速来显示实时速度。结果发现 CAR_SPEED 权限根本申请不到。后来只能通过 CarSensorManagerSENSOR_TYPE_CAR_SPEED 来读,但这个传感器数据在行驶中会被系统限制频率。嗯,这就是车载开发的现实——安全优先,功能其次。

8.4 知识体系总览

下面这张图,是我梳理的本章核心逻辑。你可以把它当作一个「地图」,后续开发时随时回来对照。

Car App 开发基础:核心知识体系 Car API 库 (android.car.*) 车辆硬件访问 · 系统服务 · UI 组件 Car App 生命周期 多窗口分屏常态 · 驾驶模式状态 (DrivingState) 音频焦点优先于 onPause 权限管理 普通权限 · 危险权限 · 车辆专属权限 (signature/privileged) 典型:CAR_SPEED, CONTROL_CAR_CLIMATE, READ_DRIVING_STATE 实践要点:签名匹配 · 角色声明 · 运行时权限弹窗 · 驾驶状态监听

8.5 开发中的几个实用技巧

最后,分享几个我在实际项目中积累的经验,希望能帮你少走弯路。

  1. 获取 Car 实例一定要判空。 车载系统启动时,Car Service 可能还没就绪。代码里务必加 null 检查。
  2. 权限申请失败要有降级方案。 比如读不到车速,就显示「车速不可用」,而不是直接崩溃。
  3. 驾驶模式变化时,及时释放资源。 比如停止视频解码、暂停高频率的传感器轮询,既能省电也符合安全规范。
  4. 多窗口模式下,注意 UI 的适配。 不要假设你的应用永远占据全屏。

一个小技巧:调试车辆专属权限时,可以用 adb shell dumpsys car_service 来查看当前应用的权限授予状态。这个命令在开发阶段非常有用,比翻日志快多了。

好了,这一章的内容就到这里。Car API 库、生命周期、权限管理,这三块是车载应用开发的基石。你把这些搞透了,后面写具体功能时就会顺手很多。


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