信号接入指北 3.0

仅以 car-lib (android) 作为(Java)调用说明,其他语言的数据结构、通信方式与此类似。

接入 MiCarPropertyService:

MiCarPropertyService 接入文档

Car-lib(Car-lib 的接入方式后续将不再支持 micar 信号获取)

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 的初始化。

车控信号定义

https://pkgs.d.xiaomi.net/ui/repos/tree/General/artifactory-snapshots/mi/car/vehicle.support/0.11.24-SNAPSHOT

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
  • 信号声明
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*/
 
// .......
}

以空调温度信号为例:

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(见原文档附件)

车辆信号调试-Q&A CarService 与 VHAL

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_SPEED
CarPropertyManager 相关异常
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 警告

信号变更通知群

📷 [图片:信号变更通知群二维码]

相关链接

车辆信号调试-Q&A CarService 与 VHAL

需特殊处理信号

Android 配置字接入指南

车机 Android 端方控实现方案

信号变更说明

DCD 车辆数据服务

信号 Status 值扩展说明

DCD 域内时钟同步策略

信号管理平台

TODO:Settings 接入信号列表

问题

  1. 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