信号接入指北 3.0
叮
仅以 car-lib (android) 作为(Java)调用说明,其他语言的数据结构、通信方式与此类似。
接入 MiCarPropertyService:
Car-lib(Car-lib 的接入方式后续将不再支持 micar 信号获取)
-
代码地址 Android Code Search
-
-
Java-Doc 不额外提供,可以参考 Android Developer
-
CarPropertyManager#registerCallback(callback, propertyId, rate)
-
[callback] - 信号变化的回调
-
[propertyId] - 具体信号 ID
-
[rate] - 期望信号接受频率,仅对 MODE_CONTINUOUS 类型信号有效(比如:车速、里程、方向盘转角等等)
💡 Continuous 信号有最大频率限制,如果信号变化频率超过设定频率,会存在信号丢失问题,设置频率为 SENSOR_RATE_ONCHANGE 则会按照 onChange 类型上报该信号。
-
-
CarPropertyManager#setProperty(clazz, propId, areaId, value)
- 与 setBooleanProperty / setFloatProperty / setIntProperty 用法类似
- [clazz] - value type
- [propId] - 具体信号 ID
- [areaId] - 方位 ID,与信号 ID 组合使用,共同确定一个具体物件,比如
Hvac#TEMPERATURE(propId) 和VehicleAreaSeat#SEAT_ROW_1_LEFT(areaId) 可以表示空调在主驾(副驾?)的目标温度 - [value] - 具体的信号值,支持 Integer, Float, Long, int[], byte[], long[], String 类型
-
CarPropertyManager#getProperty(clazz, propId, areaId)
- 使用 registerCallback 足以覆盖大部分场景
- 与 setProperty 类似,不做过多说明
-
CarPropertyManager#getPropertyList 与 CarPropertyManager#getCarPropertyConfig
- 获取当前信号配置,包含该信号可用范围、支持 Area 范围等
- 该配置在 CarService (Vhal) 中目前是静态配置,不支持运行时动态变化
- 车辆对于某功能的支持与否、支持程度,皆可通过此方法确认
-
-
car-lib 的 jar
📎 附件:car-lib jar(见原文档附件)
Car-lib 使用方法
- Gradle 编译(参考:Link)
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.xxx"
minSdkVersion 28
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
// maven { url 'https://pkgs.d.xiaomi.net:443/artifactory/maven-snapshot-virtual/' }
implementation 'mi.car:vehicle.support:0.2.2.9-SNAPSHOT'
}- bp 编译
android_app {
name: "Xxxxx",
srcs: ["src/**/*.java", "src/**/*.aidl"],
libs: [
"android.car"
],
static_libs: [
"mi-car-support-api",
],
}car-lib 接口使用示例
通过 Car 来创建 CarPropertyManager 来操作汽车属性相关的操作。后续对于信号的访问操作通过接口:mCarPropertyManager 来完成,注意使用时候判空,为 null 则可能是 carservice 异常导致。
import android.car.Car;
import android.car.hardware.property.CarPropertyManager;
private Car mCar;
private CarPropertyManager mCarPropertyManager;
private init(Context context) {
mCar = Car.createCar(
MainActivity.this,
mHandler,
Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
(car, ready) -> {
if (ready) {
CarPropertyManager cpm = (CarPropertyManager)car.getCarManager(Car.PROPERTY_SERVICE);
initCarPropertyManager(cpm);
mCarPropertyManager = cpm;
} else {
mCarPropertyManager = null;
}
});
}createCar 参数说明:
- Context:不应该为 null,确保非空,否则抛出异常。
- Handler:所有的 CarManager 事件分配到此 Handler,但异常处理(CarServiceLifecycleListener)会始终被分配到主线程,如果传入 NULL 则所有的 CarManager 事件都会被分配到主线程。
- waitTimeoutMs:将此设置为 CAR_WAIT_TIMEOUT_DO_NOT_WAIT 将保证 API 根本不会等待 Carservice Ready。将此设置为 CAR_WAIT_TIMEOUT_WAIT_FOREVER 将永远进行等待,直到汽车服务准备就绪。设置任何其他值表示超时值。
注意事项说明:
请务必使用上述接口完成 Car 的创建。如果使用 createCar(Context context, @Nullable Handler handler),如果 CarService 没有及时完成 init,App 调用方可能被阻塞 5000ms,导致 ANR;使用该接口如果 carservice 发生故障,则调用方进程也会收到牵连发生异常。
参数 waitTimeoutMs 说明:
- 使用
Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER(-1)做 createCar 的同步调用,虽然这么写代码会方便很多,但是可能会导致不可预知的等待时间。 - 建议使用
Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT(0)做异步调用,在 CarServiceLifecycleListener 中做初始化,来做 CarXxxxManager 的初始化。
车控信号定义
-
信号构成参考(PropertyId, AreaId)
-
SOA 服务接口定义表格(初版,未使用)
-
SOA 服务接口定义表格 MS11(E2/E3 备份 | 弃用)
(截止 E3,已弃用) -
SOA 服务接口定义表格 MS11(当前版本,定时更新)
-
-
SC 中信号查找参考指南:车控 SOA 信号流程查看说明(感谢小爱部门大力支持)
-
Maven 地址(版本号可从网页上查看):
maven { url 'https://pkgs.d.xiaomi.net:443/artifactory/maven-snapshot-virtual/' }
implementation 'mi.car:vehicle.support:0.1.4-SNAPSHOT'
// https://pkgs.d.xiaomi.net/artifactory/webapp/#/artifacts/browse/tree/General/artifactory-snapshots/mi/car/vehicle.support
// 或者 release
maven { url 'https://pkgs.d.xiaomi.net:443/artifactory/maven-release-virtual/' }
implementation 'mi.car:vehicle.support:0.1.4'
//https://pkgs.d.xiaomi.net/artifactory/webapp/#/artifacts/browse/tree/General/artifactory-releases/mi/car/vehicle.support最新版本查询: Link
- 信号声明
public class Hvac {
// .......
@PropertyDef(
permission = @RequiresPermission(Car.PERMISSION_CONTROL_CAR_CLIMATE),
areaRef = VehicleAreaSeat.class,
type = float.class,
value = @ValueDef(range = @Range(floatFrom = 18.0, floatTo = 32.0)))
public static final int TEMPERATURE = 0x10a
| MiVehiclePropertyGroup.MI_CAR
| MiVehicleArea.SEAT
| VehiclePropertyType.FLOAT
| MiVehicleZone.HVAC; /*0x6560410a*/
// .......
}以空调温度信号为例:
- PropertyId 为
Hvac#TEMPERATURE,其 int 的构成可参考上述中的 SOA 服务接口定义表格 MS11(E2/E3 备份 | 弃用) 与 Mi AAOS 信号体系实现 - AreaId 为 VehicleAreaSeat 类中的某个枚举值(或组合 | 按位或),比如
VehicleAreaSeat#SEAT_ROW_1_LEFT,具体支持的 Area 范围以及数据以 CarPropertyManager#getCarPropertyConfig 或车型为准,代码中的声明(ValueDef)只作为参考,不能表示具体车型的支持情况 - 注解中还说明了该信号的数据类型 type,以及读写所需要的权限 permission(标准 Android 权限体系 | Manifest),请开发人员妥善处理
Mock
常见场景切换
分心模式:
⚠️ 平台差异(2026-07 更新):newton / YU7 等 AIDL 平台用
dumpsys ...IVehicle/micar;老 HIDL 平台才用lshal debug ...@2.0::IVehicle。先用adb shell service list | grep automotive.vehicle判定(详见《车辆信号调试 Q&A》2.2)。以下为 AIDL(newton)写法,参数-i(带横杠,源码权威):
# 开启分心模式
adb root
# 切换档位至 DRIVE
adb shell dumpsys android.hardware.automotive.vehicle.IVehicle/micar --mock_from_car 1631613445 -i 3
# 模拟速度到 60
adb shell dumpsys android.hardware.automotive.vehicle.IVehicle/micar --mock_from_car 1631613441 -i 60# 关闭分心模式
adb root
# 切换档位至 PARK
adb shell dumpsys android.hardware.automotive.vehicle.IVehicle/micar --mock_from_car 1631613445 -i 0
# 模拟速度到 0
adb shell dumpsys android.hardware.automotive.vehicle.IVehicle/micar --mock_from_car 1631613441 -i 0模拟信号脚本
📎 附件:LogPropMonitor.py(模拟信号脚本,见原文档附件)
# 解析 log,并执行模拟
python LogPropMonitor.py xxxx.log
# 将 log 中模拟命令转储为 cmd_list.sh 文件
python LogPropMonitor.py xxxx.log --save_only
# 将 log 中模拟命令转换为 cmd_list.sh 文件,并执行
python LogPropMonitor.py xxxx.log --output output.sh --exec辅助测试用 APP(代码仓库)
📎 附件:CarDemo4Test.apk(见原文档附件)
adb install -t -g CarDemo4Test.apk
# APP 中打开 Mock 时候点击,和命令行注入等效
# 注入雨刮速度为 间歇高速 (Body#WIPER_SPEED_MODE)
adb shell dumpsys car_service inject-vhal-event 0x63401301 1 2
# 注入雨刮维修模式为 ON (Body#WIPER_SERVICE_MODE)
adb shell dumpsys car_service inject-vhal-event 0x63401302 1 1- 开发人员可以直接拉取代码,来更新 App(代码仓库 更新 vehicle.support 版本即可,界面是依赖信号自动生成的)
📷 [图片:Android Studio 中 CarDemo 项目 build.gradle(app),第 56 行黄色高亮 implementation ‘mi.car.vehicle.support:0.1.1.1-SNAPSHOT’ 依赖声明]
其他
- Mock 功能仅适用于信号通路完成前,debug 使用,切勿在车辆设备上使用
- 8295 上默认 Mock 关闭,pad 上默认开启
- 目前所有设备在开机后会保持默认状态(以防有人忘了清理配置)(提交 | 提交 2)
# enable mock,仅为在通路不可用时,测试 APP 使用
adb shell settings put --user 0 GLOBAL vehicle_mock_data 1
# disable mock,切换至正常模式
adb shell settings put --user 0 GLOBAL vehicle_mock_data 0注意事项
权限
- 部分信号所需权限级别是 dangerous,需要运行时授予,或者添加
(system/vendor/xxx) /etc/default-permissions/xxxxxx.xml
android.car.permission.CAR_ENERGY
android.car.permission.CAR_SPEEDCarPropertyManager 相关异常
CarInternalErrorException,
PropertyAccessDeniedSecurityException,
PropertyNotAvailableException,
PropertyNotAvailableAndRetryException,
IllegalStateException,
IllegalArgumentException-
CarPropertyManager#setProperty
- 这里 App 可以处理部分异常,CarService 目前并不会在 setProperty 的时候抛出 ServiceSpecificException,所以 App 也可以忽略处理
-
CarPropertyManager#getIntProperty, getFloatProperty, getBooleanProperty, getIntArrayProperty
- 触发原因:CarPropertyManager#handleNullAndPropertyStatus(source)
- 这里需要 App 主动处理下异常,因为这部分代码是存在于 car-lib 中的,而本地修改 car-lib 的代码并不能影响到所有 App,而且由于这里的异常都是继承自 RuntimeException,所以 IDE 也不会提示开发人员去主动处理,是个很容易忽略的问题
// 建议方式 1
int value ;
try {
value = mCarPropertyManager.getIntProperty(propId, areaId);
} catch (CarInternalErrorException
| PropertyNotAvailableAndRetryException
| PropertyNotAvailableException e1) {
// can signal timeout ? hardware fatal ?
value = -1 ;
} catch (PropertyAccessDeniedSecurityException | IllegalArgumentException e2) {
// app cannot access or error call ? 应用可以解决逻辑问题,而不去处理异常
value = -1;
}
// 建议方式 2,这里在 CarService 中做了处理,getProperty 并不会抛出异常
CarPropertyValue<Integer> carProp = mCarPropertyManager.getProperty(Integer.class, propId, areaId);
int value = carProp != null ? carProp.getValue() : -1;
// 或者对其他车机系统也做兼容处理
int value;
try {
CarPropertyValue<Integer> carProp = mCarPropertyManager.getProperty(Integer.class, propId, areaId);
value = carProp != null /*&& carProp.getStatus() == CarPropertyValue.STATUS_AVAILABLE*/
? carProp.getValue() : -1;
} catch (CarInternalErrorException
| PropertyNotAvailableAndRetryException
| PropertyNotAvailableException e1) {
// can signal timeout ? hardware fatal ?
value = -1;
} catch (PropertyAccessDeniedSecurityException | IllegalArgumentException e2) {
// app cannot access or error call ? 应用可以解决逻辑问题,而不去处理异常
value = -1;
}
// 方式3
// 额外提供方法 TODO
MiCarPropertyManager#getIntPropertySafe(
CarPropertyManager cpm,
int prop,
int area,
int defaultValue)
MiCarPropertyManager#getIntPropertySafe(
CarPropertyManager cpm,
int prop,
int area,
boolean returnOriginIfUnavaliable/**default : true**/,
int defaultValue)-
CarPropertyManager#getProperty(java.lang.Class
, int, int) - 同 setProperty,Service 端也不会主动抛出 ServiceSpecificException,开发人员可以忽略此问题,或者使用上述同样方法去处理
目前所有设备在开机后会 Mock 保持默认状态(以防有人忘了清理配置)(提交)
Create Car ANR 警告
信号变更通知群
📷 [图片:信号变更通知群二维码]
相关链接
- E3-SC:https://xiaomi.f.mioffice.cn/drive/folder/fldk4T2KFVJQaRNz9BOm9LkdRRh
- E4-SC:https://xiaomi.f.mioffice.cn/drive/folder/fldk4ME4bI9xq0QhfjkBZ95LdQh
- E4U-SC:https://xiaomi.f.mioffice.cn/drive/folder/fldk4Bdzf8Hvh3hBlFVlxh7sZec
TODO:Settings 接入信号列表
问题
- AGP 版本不匹配问题导致 gradle 编译报错。
> Task :mergeExtDexDcdDebug FAILED
AGPBI: {"kind":"error","text":"java.lang.NullPointerException: Cannot invoke \"String.length()\" because \"<parameter1>\" is null","sources":[{"file":"/Users/zhaoguohui/.gradle/caches/transforms-3/1b8dfb661cb130ec9d8ffcd765da35c8/transformed/jetified-vehicle.support-0.11.20-SNAPSHOT.jar"}],"tool":"D8"}
Execution failed for task ':mergeExtDexDcdDebug'.
> Could not resolve all files for configuration ':dcdDebugRuntimeClasspath'.
> Failed to transform vehicle.support-0.11.20-SNAPSHOT.jar (mi.car:vehicle.support:0.11.20-SNAPSHOT:20250730.120023-1) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-is-debuggable=true, dexing-min-sdk=30, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=integration, org.gradle.usage=java-runtime}.
> Execution failed for DexingNoClasspathTransform: /Users/zhaoguohui/.gradle/caches/transforms-3/1b8dfb661cb130ec9d8ffcd765da35c8/transformed/jetified-vehicle.support-0.11.20-SNAPSHOT.jar.
> Error while dexing.解决方案:https://issuetracker.google.com/issues/342522142#comment8