3. 监听车辆属性变化
任务说明
在Android Car服务中,车辆属性(如车速、挡位、充电状态等)由CarPropertyService统一管理。本案例实现一个可独立运行的监听模块:注册CarPropertyEventCallback,实时接收指定属性ID的变化回调,并将属性值变化打印到日志中,同时提供手动取消注册的入口。
环境与依赖
- Android 10+(API 29+),系统签名或具备
android.car.permission.CAR_INFO权限 - 依赖
android.car.Car、android.car.VehiclePropertyIds、android.car.property.CarPropertyManager - 需在Android Studio中创建Car App工程,并在
AndroidManifest.xml中声明权限:
<uses-permission android:name="android.car.permission.CAR_INFO" />
<uses-permission android:name="android.car.permission.CAR_SPEED" />
关键完整代码
import android.car.Car;
import android.car.CarInfoManager;
import android.car.VehiclePropertyIds;
import android.car.property.CarPropertyEventCallback;
import android.car.property.CarPropertyManager;
import android.car.property.PropertyEvent;
import android.content.Context;
import android.util.Log;
import java.util.List;
public class VehiclePropertyListener {
private static final String TAG = "VehiclePropListener";
private final Context context;
private Car car;
private CarPropertyManager propertyManager;
private CarPropertyEventCallback callback;
private boolean isRegistered = false;
// 监听的车速属性ID(单位:m/s)
private static final int PROPERTY_ID = VehiclePropertyIds.PERF_VEHICLE_SPEED;
public VehiclePropertyListener(Context context) {
this.context = context;
}
/** 连接Car服务并注册监听,需在Car服务可用后调用 */
public void startListening() {
if (car == null) {
car = Car.createCar(context, (Car car) -> {
if (car != null) {
this.car = car;
propertyManager = (CarPropertyManager) car.getCarManager(Car.PROPERTY_SERVICE);
registerCallback();
} else {
Log.e(TAG, "Car service connection failed");
}
});
} else {
registerCallback();
}
}
private void registerCallback() {
if (propertyManager == null || isRegistered) return;
callback = new CarPropertyEventCallback() {
@Override
public void onChangeEvent(CarPropertyValue value) {
// 实时处理属性变化
float speed = (float) value.getValue();
Log.i(TAG, "Speed changed: " + speed + " m/s (" + (speed * 3.6) + " km/h)");
}
@Override
public void onErrorEvent(int propertyId, int zone) {
Log.e(TAG, "Error on property: " + propertyId + ", zone: " + zone);
}
};
// 注册监听,仅监听PERF_VEHICLE_SPEED属性
propertyManager.registerPropertyCallback(PROPERTY_ID, callback);
isRegistered = true;
Log.i(TAG, "Listener registered for property: " + PROPERTY_ID);
}
/** 取消注册并断开Car服务连接 */
public void stopListening() {
if (propertyManager != null && callback != null && isRegistered) {
propertyManager.unregisterPropertyCallback(PROPERTY_ID, callback);
isRegistered = false;
Log.i(TAG, "Listener unregistered");
}
if (car != null) {
car.disconnect();
car = null;
propertyManager = null;
}
}
}
调用方式
// 在Activity或Service中
VehiclePropertyListener listener = new VehiclePropertyListener(context);
listener.startListening(); // 开始监听
// 页面销毁或不再需要时
listener.stopListening(); // 停止监听并释放资源
验证方法
- 将应用部署到支持Car服务的模拟器或实车(需系统签名)
- 启动应用,调用
startListening()后观察Logcat:
adb logcat -s VehiclePropListener:I
- 模拟车辆速度变化(实车行驶或模拟器发送属性变化事件),预期看到类似日志:
VehiclePropListener: Listener registered for property: 291
VehiclePropListener: Speed changed: 10.5 m/s (37.8 km/h)
通过条件:日志中出现Listener registered,且车辆速度变化时能持续打印Speed changed日志;调用stopListening()后不再收到变化回调。
常见问题
- 权限不足:若未使用系统签名或缺少CAR_SPEED权限,注册回调会抛出
SecurityException,需在registerCallback()中捕获处理。 - 属性ID不匹配:不同车型对
PERF_VEHICLE_SPEED的支持可能不同,可改用VehiclePropertyIds.SPEED(需额外权限)或先通过getPropertyList()确认可用属性。 - 回调不触发:确认车辆实际运动且属性值发生变化;部分模拟器需手动注入属性变化事件。