版权声明
凡未经作者授权,任何媒体、网站及个人不得转载、复制、重制、改动、展示或使用局部或全部的内容或服务。如果已转载,请自行删除。同时,我们保留进一步追究相关行为主体的法律责任的权利。
© 2023 小酥肉不加辣,All rights reserved.
1. Android Automotive 平台和 Vehicle Property
什么是 Android Automotive 平台?
Android Automotive 是基于 Android 操作系统的汽车嵌入式平台。与传统的车载系统相比,Android Automotive 提供了更丰富的用户体验和应用程序生态系统。它的目标是使驾驶员和乘客能够更轻松地使用汽车中的各种功能和服务,包括导航、媒体、通信、安全和驾驶辅助等。
Android Automotive 平台的开发和使用涉及到许多技术和工具,包括 Android 开发工具、汽车硬件和软件接口、安全性和隐私保护等。
什么是Vehicle Property?
Vehicle Property 是 Android Automotive 平台中的一个关键概念,它代表了车辆的各种属性或状态。例如,车速、加速度、转向角度、引擎转速、空调状态等都可以用 Vehicle Property 来描述和获取。
Vehicle Property 提供了一种统一的方式来访问和控制汽车系统中的数据和功能。它可以被用于开发各种类型的汽车应用程序和服务,如驾驶分析、车辆诊断、车辆监控、导航等。同时,Vehicle Property还可以通过与其他 Android 组件(如Activity、Service和Broadcast Receiver)的交互来扩展应用程序的功能和用户体验。
Vehicle Property 通过标准化的 API 和数据模型来实现,并在 Android Automotive 平台中得到广泛支持。在获取 Vehicle Property 数据之前,必须获得相应的权限并遵守安全和隐私保护规定。
2. 获取 Vehicle Property
如何访问 Vehicle Property?
要访问 Vehicle Property,首先需要获得相应的权限。这可以通过在 AndroidManifest.xml 文件中声明或动态请求权限来完成。以下是一个示例:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
...
<uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE" />
...
</manifest>
在获得权限后,可以通过Car API来访问Vehicle Property。Car API是Android Automotive平台提供的一个标准API,可以在应用程序中使用。
以下是获取汽车手刹的状态的示例代码:
val on = carPropertyManager.getBooleanProperty(
VehiclePropertyIds.PARKING_BRAKE_ON,
VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL
)
Logger.i("Car parking brake property value is $on")
其中 CarPropertyManager 的实例对象是通过 Hilt 注入的单例,注意在初始化 CarPropertyManager 之前先要创建 Car 对象。
@InstallIn(SingletonComponent::class)
@Module
object ApplicationModule {
@Provides
@Singleton
fun provideCar(@ApplicationContext context: Context): Car {
return Car.createCar(context)
}
@Provides
@Singleton
fun provideCarPropertyManager(car: Car): CarPropertyManager {
return car.getCarManager(Car.PROPERTY_SERVICE) as CarPropertyManager
}
}
如何查看支持的 Property 列表
- 查询官方文档,所有的 Property 都在
VehiclePropertyIds类中声明。 - 查询 AOSP 源码的 VehicleProperty.aidl 类,这个类中在 AIDL 中声明了所有的 Property。也可以查看 types.hal 文件,但是 HIDL 的方式会逐渐被抛弃,被 AIDL 替代。
3. 监听 Vehicle Property 的数据变化
在应用程序中,我们通常需要实时获取 Vehicle Property 数据的变化,以便对其进行相应的处理。Android Automotive 平台的 CarPropertyManager 类的 registerCallback 方法可以使用注册监听器的方式,监听数据的变化。
以下是监听空调温度变化的示例:
private var hvacTemperatureListener = object : CarPropertyManager.CarPropertyEventCallback {
override fun onChangeEvent(value: CarPropertyValue<Any>) {
Logger.i("Car HVAC property value changed $value")
}
override fun onErrorEvent(propId: Int, zone: Int) {
Logger.w("Received error car property event, propId=$propId")
}
}
init {
carPropertyManager.registerCallback(
hvacTemperatureListener,
VehiclePropertyIds.HVAC_TEMPERATURE_SET,
CarPropertyManager.SENSOR_RATE_ONCHANGE
)
}
override fun onCleared() {
carPropertyManager.unregisterCallback(hvacTemperatureListener)
super.onCleared()
}
4. 解析 Vehicle Property 数据
获取到 Vehicle Property 数据后,我们需要对其进行解析,以便在应用程序中使用。解析过程通常需要依据不同的 Vehicle Property 类型来进行,以下是几种常见的 Vehicle Property 类型及其解析方法:
布尔类型(Boolean)
布尔类型的 Vehicle Property 数据通常表示一个开关状态,例如手刹是否拉起,车灯是否开启等等。对于布尔类型的数据,我们可以直接将其转换为布尔类型的变量,例如:
val isHandBrakePulled = event.value as Boolean
整数类型(Integer)
整数类型的 Vehicle Property 数据通常表示一个数值,例如车速、转速等等。对于整数类型的数据,我们可以直接将其转换为整数类型的变量,例如:
val speed = event.value as Int
有些 Vehicle Property 数据是由多个整数值组成的,例如 GPS 数据中的经度和纬度。这种情况下,我们需要将多个整数值组合起来,例如:
val latLongValue = event.value as Long
val latitude = latLongValue shr 32
val longitude = latLongValue and 0xFFFFFFFFL
浮点类型(Float)
浮点类型的 Vehicle Property 数据通常表示一个带小数点的数值,例如油量、温度等等。对于浮点类型的数据,我们可以直接将其转换为浮点类型的变量,例如:
val temperature = event.value as Float
枚举类型(Enum)
枚举类型的 Vehicle Property 数据通常表示一组固定的选项,例如档位、行车模式等等。对于枚举类型的数据,我们需要根据其选项列表来进行解析。例如,对于档位数据,可以使用以下代码将其转换为字符串:
val gearPosition = event.value as Int
val gearPositionString = when (gearPosition) {
CarSensorManager.GEAR_NEUTRAL -> "Neutral"
CarSensorManager.GEAR_PARK -> "Park"
CarSensorManager.GEAR_DRIVE -> "Drive"
CarSensorManager.GEAR_REVERSE -> "Reverse"
else -> "Unknown"
}
字符串类型(String)
字符串类型的 Vehicle Property 数据通常表示一个文本内容,例如音乐名称、车牌号等等。对于字符串类型的数据,我们可以直接将其转换为字符串类型的变量,例如:
val songTitle = event.value as String
以上是几种常见的 Vehicle Property 类型及其解析方法。在实际应用中,我们需要根据具体的 Vehicle Property 类型和数据结构来进行解析。在解析过程中,我们还需要注意数据类型转换的正确性和异常情况的处理。
5. 设置 Vehicle Property
除了获取 Vehicle Property 数据和监听其变化外,Android Automotive 平台还支持操作 Vehicle Property 数据,例如控制车灯、喇叭、座椅等等。跟获取 Property 一样,设置 Property 也需要声明所需要的权限。当然不是每个属性都可以设置,具体要看这个属性在声明的时候的权限类型,比如空调风速的属性,从注释看是可读写的属性,
/**
* Fan speed setting
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:READ_WRITE
*/
HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000 + 0x00400000,
// VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
而空调实际风速则是只读的属性。
/**
* Actual fan speed
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:READ
*/
HVAC_ACTUAL_FAN_SPEED_RPM = 0x050F + 0x10000000 + 0x05000000 + 0x00400000,
// VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
以下是设置空调风速的示例:
fun setHvacFanSpeed(speed: Int) {
try {
carPropertyManager.setIntProperty(
VehiclePropertyIds.HVAC_FAN_SPEED,
HVAC_FAN_SPEED_AREA,
speed
)
} catch (e: IllegalArgumentException) {
Logger.e("set HVAC fan speed fail", e)
}
}
其中 HVAC_FAN_SPEED_AREA 是定义的常量,包含了车内所有的座位区域。
companion object {
private const val HVAC_FAN_SPEED_AREA = VehicleAreaSeat.SEAT_ROW_1_LEFT or
VehicleAreaSeat.SEAT_ROW_1_RIGHT or VehicleAreaSeat.SEAT_ROW_2_LEFT or
VehicleAreaSeat.SEAT_ROW_2_CENTER or VehicleAreaSeat.SEAT_ROW_2_RIGHT
}
6. 总结
Android Automotive 平台提供了许多 Vehicle Property,可以方便地读取和设置车辆的状态信息,如车速、发动机转速、车窗状态等。使用 Vehicle Property,我们可以开发许多有用的车载应用程序,如车载导航、音乐播放器、智能家居控制等等。
在本文中,我们介绍了如何使用 Android 13 版本的 API 读取和设置 Vehicle Property,包括如何获取 Car 对象、如何获取 Vehicle Property 以及如何读取和设置 Vehicle Property 数据。
希望本文能帮助读者了解如何使用 Android Automotive 平台操作 Vehicle Property 数据,并在车载应用程序开发中发挥作用。