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 组件类:比如
CarUiText、CarDrawable,专门适配车载大屏的交互规范。
你想想看,手机应用能随便调用 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 |
| 危险权限 | 运行时弹窗申请 | CAMERA、RECORD_AUDIO |
| 车辆专属权限 | 系统签名 / 平台角色 | CONTROL_CAR_CLIMATE、READ_VEHICLE_SPEED |
这里重点说车辆专属权限。它们通常定义在 platform.xml 或 car\_service\_permissions.xml 中。比如你想读取车速:
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.car.permission.CAR_SPEED" />
但光声明没用。这个权限是 signature 级别的,意味着只有和系统用同一签名密钥签名的应用才能获取。第三方应用?没戏。
避坑指南:我曾经在开发一个第三方导航应用时,想获取车速来显示实时速度。结果发现 CAR_SPEED 权限根本申请不到。后来只能通过 CarSensorManager 的 SENSOR_TYPE_CAR_SPEED 来读,但这个传感器数据在行驶中会被系统限制频率。嗯,这就是车载开发的现实——安全优先,功能其次。
8.4 知识体系总览
下面这张图,是我梳理的本章核心逻辑。你可以把它当作一个「地图」,后续开发时随时回来对照。
8.5 开发中的几个实用技巧
最后,分享几个我在实际项目中积累的经验,希望能帮你少走弯路。
- 获取 Car 实例一定要判空。 车载系统启动时,Car Service 可能还没就绪。代码里务必加 null 检查。
- 权限申请失败要有降级方案。 比如读不到车速,就显示「车速不可用」,而不是直接崩溃。
- 驾驶模式变化时,及时释放资源。 比如停止视频解码、暂停高频率的传感器轮询,既能省电也符合安全规范。
- 多窗口模式下,注意 UI 的适配。 不要假设你的应用永远占据全屏。
一个小技巧:调试车辆专属权限时,可以用 adb shell dumpsys car_service 来查看当前应用的权限授予状态。这个命令在开发阶段非常有用,比翻日志快多了。
好了,这一章的内容就到这里。Car API 库、生命周期、权限管理,这三块是车载应用开发的基石。你把这些搞透了,后面写具体功能时就会顺手很多。