版权声明
凡未经作者授权,任何媒体、网站及个人不得转载、复制、重制、改动、展示或使用局部或全部的内容或服务。如果已转载,请自行删除。同时,我们保留进一步追究相关行为主体的法律责任的权利。
© 2023 小酥肉不加辣,All rights reserved.
前言
如果你还不知道如何开始在 Android Automotive OS 上开发车机应用,请阅读我的另一篇文章《如何开始在 Android Automotive OS 上开发应用》。另外,也可以订阅我的车机开发专栏,及时阅读我的最新文章。
本文主要讲述如何访问汽车传感器数据。
正文
假设我们已经搭建好开发环境,并已经新建一个空白的 Android Automotive 项目。
第一步,我们需要在模块构建文件中添加一个库引用:
android {
...
useLibrary 'android.car'
...
}
然后,我们需要声明一个 Car
对象,它将负责和汽车建立连接并获取具体的汽车管理类:
class MainActivity : AppCompatActivity() {
private lateinit var car : Car
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
现在我们已准备好创建 Car
对象并与汽车服务建立连接。
在初始化之前,我们应该检查系统是否支持汽车功能。否则,我们对 Car API
的调用可能会抛出异常。
在此之后,我们可以使用 Car API
提供的静态方法 createCar()
初始化 Car
对象,并在其中两个函数回调中处理建立连接成功和失败的逻辑。
override fun onCreate(savedInstanceState: Bundle?) {
initCar()
}
private fun initCar() {
if (!packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
return
}
if(::car.isInitialized) {
return
}
car = Car.createCar(this, object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) {
onCarServiceReady()
}
override fun onServiceDisconnected(componentName: ComponentName) {
// on failure callback
}
})
}
private fun onCarServiceReady() {
// Do something
}
下一步是建立一个与汽车服务的连接,并让我们的应用程序在 Activity
生命周期中正确地管理它。
实现此目的的最佳方法是在 onResume()
和 onPause()
中调用适当的方法。
...
override fun onResume() {
super.onResume()
if (!car.isConnected && !car.isConnecting) {
car.connect()
}
}
override fun onPause() {
if(car.isConnected) {
car.disconnect()
}
super.onPause()
}
...
现在打开模拟器,看一下有哪些传感器数据
以车辆速度为例,我们可以尝试从速度传感器收集数据。让我们创建一个名为 watchSpeedSensor()
的方法,并使用 Car.SENSOR_SERVICE
初始化 CarSensorManager
。然后注册一个监听器来接收传感器数据。
private fun watchSpeedSensor() {
val sensorManager = car.getCarManager(Car.SENSOR_SERVICE) as CarSensorManager
sensorManager.registerListener(
{ carSensorEvent ->
Log.d("MainActivity", "Speed: ${carSensorEvent.floatValues[0]}")
},
CarSensorManager.SENSOR_TYPE_CAR_SPEED,
CarSensorManager.SENSOR_RATE_NORMAL
)
}
当前的代码还不能运行,因为需要申请特定的权限才可以正常使用,以下列出所有的传感器数据及对应的权限:
Sensor | Permission |
---|---|
Speed | PERMISSION_SPEED |
Gear | PERMISSION_POWERTRAIN |
Night mode | PERMISSION_EXTERIOR_ENVIRONMENT |
Fuel level | PERMISSION_ENERGY |
ABS | PERMISSION_CAR_DYNAMICS_STATE |
现在,我们在 AndroidManifest.xml 文件中添加一行:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.car">
...
<uses-permission android:name="android.car.permission.CAR_SPEED" />
...
</manifest>
下一步,在连接之前检查权限是否已经授权
class MainActivity : AppCompatActivity() {
private lateinit var car : Car
private val permissions = arrayOf(Car.PERMISSION_SPEED)
...
override fun onResume() {
super.onResume()
if(checkSelfPermission(permissions[0]) == PackageManager.PERMISSION_GRANTED) {
if (car?.isConnected == false && car?.isConnecting == false) {
car?.connect()
}
} else {
requestPermissions(permissions, 0)
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (permissions[0] == Car.PERMISSION_SPEED && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (!car.isConnected && !car.isConnecting) {
car.connect()
}
}
}
private fun onCarServiceReady() {
watchSpeedSensor()
}
private fun watchSpeedSensor() {
val sensorManager = car.getCarManager(Car.SENSOR_SERVICE) as CarSensorManager
sensorManager.registerListener(
{ carSensorEvent ->
Log.d("MainActivity", "Speed: ${carSensorEvent.floatValues[0]}")
},
CarSensorManager.SENSOR_TYPE_CAR_SPEED,
CarSensorManager.SENSOR_RATE_NORMAL
)
}
}
运行之后,查看结果:
D/MainActivity: Speed: 1.0
D/MainActivity: Speed: 2.0
D/MainActivity: Speed: 3.0
D/MainActivity: Speed: 4.0
D/MainActivity: Speed: 5.0
D/MainActivity: Speed: 6.0
D/MainActivity: Speed: 7.0
D/MainActivity: Speed: 8.0
D/MainActivity: Speed: 9.0
D/MainActivity: Speed: 10.0
D/MainActivity: Speed: 11.0
D/MainActivity: Speed: 10.0
D/MainActivity: Speed: 11.0
D/MainActivity: Speed: 12.0
D/MainActivity: Speed: 13.0
D/MainActivity: Speed: 14.0
D/MainActivity: Speed: 15.0
D/MainActivity: Speed: 16.0
好了,现在你的 App 可以读取传感器的数据了。