文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android汽车服务篇(三) CarPropertyService下篇

2023-09-05 09:28

关注

一. 简介

        上篇文章介绍了Android汽车服务篇(二) CarPropertyService上篇, 我们继续看一看看CarPropertyService, 这个服务也是很重要的, 绝大部分与车辆硬件功能相关联的属性,如空调, 车舱功能, 车辆传感器等都是通过CarPropertyService来读取或者设置的.

         CarPropertyManager 是CarPropertyService在客户端的代理, 通过CarPropertyManager提供的API,可以设置和获取车辆各个属性的状态.

二. 座舱服务 CarCabinManager

        CarCabinManager提供的是座舱内相关功能的API, 包括座椅,安全带,车窗等. 它在用法上和CarHvacManager类似, 同样的CarCabinManager也是系统级别的,只有拥有系统权限的应用才可以使用.

        CarCabinManager的属性

CarCabinManager中的属性都和座舱内的硬件设备相关,如车门,后视镜,座椅等. 与这些设备相关的属性又根据其特点进行了细分,对于可以移动,调节的设备而言,会有不同方向之分.

下表中的列出了CarCabinManager中所包含的属性, 以及属性所对应的主要设备和功能

属性类型功能
ID_DOOR_POSint车门
ID_DOOR_MOVEint
ID_DOOR_LOCKbool
ID_MIRROR_Z_POSint后视镜
ID_MIRROR_Z_MOVEint
ID_MIRROR_Y_POSint
ID_MIRROR_Y_MOVEint
ID_MIRROR_LOCK

bool

ID_MIRROR_FOLDbool
ID_SEAT_MEMORY_SELECT

int

座椅记忆
ID_SEAT_MEMORY_SET

int

ID_SEAT_BELT_BUCKLED

bool

安全带
ID_SEAT_BELT_HEIGHT_POSint
ID_SEAT_BELT_HEIGHT_MOVEint
ID_SEAT_FORE_AFT_POSint座椅前后位置
ID_SEAT_FORE_AFT_MOVEint
ID_SEAT_BACKREST_ANGLE_1_POSint座椅靠背
ID_SEAT_BACKREST_ANGLE_1_MOVEint
ID_SEAT_BACKREST_ANGLE_2_POSint
ID_SEAT_BACKREST_ANGLE_2_MOVEint
ID_SEAT_HEIGHT_POSint座椅高度
ID_SEAT_HEIGHT_MOVEint
ID_SEAT_DEPTH_POSint座椅深度
ID_SEAT_DEPTH_MOVEint

                                                                               表一

属性类型功能
ID_SEAT_TILT_POSint座椅倾角
ID_SEAT_TILT_MOVEint
ID_SEAT_LUMBAR_FORE_AFT_POSint腰托
ID_SEAT_LUMBAR_FORE_AFT_MOVEint
ID_SEAT_LUMBAR_SIDE_SUPPORT_POSint
ID_SEAT_LUMBAR_SIDE_SUPPORT_MOVEint
ID_SEAT_HEADREST_HEIGHT_POSint头枕
ID_SEAT_HEADREST_HEIGHT_MOVEint
ID_SEAT_HEADREST_ANGLE_POSint
ID_SEAT_HEADREST_ANGLE_MOVEint
ID_SEAT_HEADREST_FORE_AFT_POSint
ID_SEAT_HEADREST_FORE_AFT_MOVEint
ID_WINDOW_POSint车窗
 
ID_WINDOW_MOVEint
ID_WINDOW_LOCKbool

                                                                                 表二

        可以看到CarCabinManager中最主要的是和座椅相关的属性,同时还有车窗,后视镜相关的功能. 大部分功能同时会有位置(position)和移动(move)两个属性.其中位置属性主要是设置具体的位置值而移动则是该设备的移动方向.

        

        CarCabinManager丰富了车内设施的控制功能,通过它提供的API,开发者可以为驾驶者提供很多个性化的功能,如座椅调节, 车窗调节

        在用法上, CarCabinManager和CarHvacManager非常相似,同样可以获取或设置属性的值, 并对属性变化进行监听. API也没有什么两样. 

        相关的权限主要有以下三个:

      

三. 制造商扩展服务 CarVendorExtensionManager

        市场上的汽车品牌种类繁多,每款车型的功能又不相同.汽车制造商们也在不断推陈出新,推出一些属于品牌特有的功能来吸引消费者的目光. 要想将说有的功能都定义为标准的属性肯定非常困难.

        对此 AAOS的做法是, 除了定义目前市场上绝大多数车型都适用的属性外,同样允许制造商根据自己所拥有的其他功能进行扩展, 这就是本节CarVendorExtensionManager的主要作用. 它让制造商可以扩展VehicleHAL中已经定义的属性,加入额外的功能.

 3.1 CarVendorExtensionManager用法

通过以下方式获取CarVendorExtensionManager对象的实例

        Car car = Car.createCar(this);        CarVendorExtensionManager vendorManager = (CarVendorExtensionManager)car.getCarManager(Car.VENDOR_EXTENSION_SERVICE);

要使用CarVendorExtensionManager需要申请如下权限:

该权限同时是系统级别的,普通的第三方应用无法使用.

3.2 获取和设置属性

        在属性的设置或获取上, CarVendorExtensionManager和CarHvacManager. CarCabinManager的使用方法区别并不大, 但是由于是扩展的属性, 属性的类型是不确定的,所以在调用setProperty和getProperty时需要传入属性的类型. 

        举个例子, 自定义了一个 CUSTOM_FLOAT_AREA 属性,且值为float型,如果该区域是多区域的,还需要传入区域值, 获取和设置该属性的方法如下:

        //设置属性值        vendorManager.setProperty(Float.class, CUSTOM_FLOAT_AREA, VehicleAreaSeat.SEAT_ROW_1_CENTER, value);        //获取实际值        float actualVaule = vendorManager.getProperty(Float.class, CUSTOM_FLOAT_AREA, VehicleAreaSeat.SEAT_ROW_1_CENTER);

我们可以看看packages/services/Car/car-lib/src/android/car/hardware/CarVendorExtensionManager.java 的 这两个方法

 public  void setProperty(Class propertyClass, int propId, int area, E value) {        mPropertyManager.setProperty(propertyClass, propId, area, value);} public  E getProperty(Class propertyClass, int propId, int area) {        return mPropertyManager.getProperty(propertyClass, propId, area).getValue();    }

3.3 监听属性变化

CarVendorExtensionManager同样可以通过注册回调接口的方式来监听属性值发生的变化. 方式十分简单.实现CarVendorExtensionCallback就可以了.方式如下:

         //创建一个监听器对象        CarVendorExtensionListener listener = new CarVendorExtensionListener();        //注册监听器        vendorManager.registerCallback(listener);        //移除监听器        vendorManager.unregisterCallback(listener);class CarVendorExtensionListener implements CarVendorExtensionManager.CarVendorExtensionCallback{    @Override    public void onChangeEvent(CarPropertyValue carPropertyValue) {    }    @Override    public void onErrorEvent(int i, int i1) {    }}

需要注意的是, 尽管注册的是CarVendorExtensionCallback,但是该回调方法不仅会收到扩展属性相关的变化事件,对于其他属性的变化事件(如空调,传感器)也有可能被传递过里. 因此在onChangeEvent方法中需要做好相关的判断,确保该次事件是所需要的.

有了CarVendorExtensionManager, CarService一下子有了拥有扩展属性的能力,让原来看上去有限的功能,变得可以丰富无比,当然实际上还是得依赖制造商的实现.  

对于需要使用自定义属性的应用, 只需要知道确切的ID和类型.

四.  车辆属性API  CarPropertyManager

本节介绍最重要的一个Manager :  CarPropertyManager. 在Android10中,它变成了车辆属性的主要API, 并允许任何运行在 AAOS上的应用进行调用. 

4.1 CarPropertyManager用法

        熟悉了上面介绍的5个服务的相关用法后,在CarPropertyManager的使用上, 对相关的用法有所了解, 接下来这里再做一点补充.

        关于属性的获取, 在CarPropertyManager.java中除了有getProperty方法之外, 还有getBooleanProperty. getIntProperty这样明确属性类型的获取方法. 这些方法的最后实现还是对getProperty方法的封装.

        public int getIntProperty(int prop, int area) {        //最后还是调用的getProperty方法        CarPropertyValue carProp = getProperty(Integer.class, prop, area);        return carProp != null ? carProp.getValue() : 0;    }public  CarPropertyValue getProperty(@NonNull Class clazz, int propId, int areaId) {        if (DBG) {            Log.d(TAG, "getProperty, propId: 0x" + toHexString(propId)                    + ", areaId: 0x" + toHexString(areaId) + ", class: " + clazz);        }        try {            CarPropertyValue propVal = mService.getProperty(propId, areaId);            if (propVal != null && propVal.getValue() != null) {                Class actualClass = propVal.getValue().getClass();                if (actualClass != clazz) {                    throw new IllegalArgumentException("Invalid property type. " + "Expected: "+ clazz + ", but was: " + actualClass);                }            }            return propVal;        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }    }

注意事项:  官方推荐开发者使用getProperty来获取相应的属性值, 因为getProperty方法返回的是CarPropertyValue对象,其不仅仅包含属性值,还包括属性的状态,而getIntProperty等方法在属性不可用的情况下,返回的是默认值,所以会造成有些时候读取的数据不准确.

下面已NIGHT_MODE(昼夜模式)属性为例子, 说明使用getProperty的好处.

private void testCarPropertyManager() {        Car car = Car.createCar(this);        CarPropertyManager carProperty = (CarPropertyManager)car.getCarManager(Car.PROPERTY_SERVICE);        CarPropertyValue val = carProperty.getProperty(Boolean.class, NIGHT_MODE, 0);        if(val == null || val.getStatus() != CarPropertyValue.STATUS_AVAILABLE) {            // 该属性不支持或不可用, 使用当前时间判断昼夜情况        } else if (val.getValue()) {            //黑夜模式        } else {            //白昼模式        }    }

虽然getProperty 方法会增加源码的数量,  但还是推荐大家使用该方式获取属性.

在设置属性方面, CarPropertyManager同样提供了setProperty以及明确类型的setIntProperty, setBooleanProperty等方法. 当然这些方法最后还是调用的setProperty.

  public void setBooleanProperty(int prop, int areaId, boolean val) {        setProperty(Boolean.class, prop, areaId, val);    }   public void setFloatProperty(int prop, int areaId, float val) {        setProperty(Float.class, prop, areaId, val);    }    //最终调用的还是这个方法    public  void setProperty(@NonNull Class clazz, int propId, int areaId, @NonNull E val) {        if (DBG) {            Log.d(TAG, "setProperty, propId: 0x" + toHexString(propId)                    + ", areaId: 0x" + toHexString(areaId) + ", class: " + clazz + ", val: " + val);        }        try {            mService.setProperty(new CarPropertyValue<>(propId, areaId, val));        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }    }

4.2 注册监听器

在注册监听属性变化方面, CarPropertyManager提供更细的监听方法, 它可以监听到单个属性值的变化, 开发者可以通过在注册监听器时传入属性ID指定监听器所对应的属性. 同时指定数据上报的频率.

        //注册监听器        CarPropertyListener carPropertyListener = new CarPropertyListener();        carProperty.registerCallback(carPropertyListener, VehiclePropertyIds.PERF_VEHICLE_SPEED, 6);        //移除监听器        carProperty.unregisterCallback(carPropertyListener);class CarPropertyListener implements  CarPropertyManager.CarPropertyEventCallback{    @Override    public void onChangeEvent(CarPropertyValue carPropertyValue) {    }    @Override    public void onErrorEvent(int i, int i1) {    }}

4.3 CarPropertyManager相关类

前文已经提到过CarInfoManager, CarHvacManager, CarSensorManager 都是通过CarPropertyManager实现其功能的. 在其他几个Manager初始化的时候,都会创建属于自己的CarPropertyManager对象. 这几个Manager拥有了CarPropertyManager以后用来做什么呢?

/packages/services/Car/car-lib/src/android/car/CarInfoManager.java

    public float getFuelCapacity() {        return mCarPropertyMgr.getFloatProperty(BASIC_INFO_FUEL_CAPACITY, 0);    }        CarInfoManager(IBinder service) {        ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);        //在构造方法中创建CarPropertyManager对象        mCarPropertyMgr = new CarPropertyManager(mCarPropertyService, null);    }

packages/services/Car/car-lib/src/android/car/hardware/hvac/CarHvacManager.java

    public boolean getBooleanProperty(@PropertyId int propertyId, int area) {        return mCarPropertyMgr.getBooleanProperty(propertyId, area);    }    public CarHvacManager(IBinder service, Context context, Handler handler) {        ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);        //构造方法中 创建CarPropertyManager对象        mCarPropertyMgr = new CarPropertyManager(mCarPropertyService, handler);    }

原来这些Manager就是对CarPropertyManager的调用,其他几个Manager并没有做什么具体的事情,只是把任务交给了CarPropertyManager再去执行.

在前面文章中出现了如VehiclePropertyIds,  CarPropertyValue, CarPropertyConfig等相关的辅助类. 我们在这里梳理一下各个辅助类的作用

辅助类名称功能作用
VehiclePropertyIds

CarPropertyManager都是通过属性ID来对应具体的功能,不同的功能对应不同的ID

VehiclePropertyIds中列出了所有在VehicleHAL中定义的功能属性

VehicleAreaDoor许多功能点都分为多个区域,在设置,获取相应属性时,需要传入区域参数,VehicleAreaDoor定义了与车门相关的区域值,在使用和车门相关的属性时配套使用
VehicleAreaMirror与VehicleAreaDoor类似, 多区域定义, 后视镜区域值
VehicleAreaSet多区域定义, 座位区域值
VehicleAreaWheel多区域定义, 车胎区域值
VehicleAreaWindow多区域定义,车窗区域值
VehicleAreaType

区域类型是用来区分一个属性所对应的位置, 源码类中有6个值:VEHICLE_AREA_TYPE_GLOBAL 对应于非多区域

VEHICLE_AREA_TYPE_WINDOW(车窗)

VEHICLE_AREA_TYPE_SEAT(座椅)

VEHICLE_AREA_TYPE_DOOR(车门)

VEHICLE_AREA_TYPE_MIRROR(后视镜)

VEHICLE_AREA_TYPE_WHEEL(轮胎)

VehicleLightState灯光状态  开    关    日间
VehicleLightSwitch灯光切换, 开   关     日间      自动
VehicleOilLevel油量状态

以上这些辅助类中,都定义了相关的静态变量,同时这些值都是与VehicleHAL的相关定义是一一对应的.在Car API中将其再次定义是为了方便上层应用使用.

我们也还经常用到CarPropertyConfig 和 CarPropertyValue这两个模板类.

辅助类功能
CarPropertyConfig获取一个属性的静态参数, 如取值范围,类型,支持的区域等
CarPropertyValue获取一个属性的值和状态

我们先看看CarPropertyConfig它的成员变量列表

类型变量名说明
intmAccess该属性是否可读可写(0:不可读不可写;  1:可读;  2:可写;  3:可读写)
intmAreaType区域类型,与VehicleAreaType对应
intmChangeMode变化类型(0:该属性值始终不变; 1:发生变化时通知; 2:以一定频率持续通知当前值)
ArrayListmConfigArray额外的配置属性
StringmConfigString额外的配置信息
floatmMaxSampleRate最大频率(仅对持续上报属性有效)
floatmMinSampleRate最小频率(仅对持续上报属性有效)
intmPropertyId属性ID
SparseArray>mSupportedAreas区域属性,包含该区域的取值范围
ClassmType属性的类型

看下这个例子, 通过CarPropertyManager获取当前车辆支持的属性(需要在清单文件中声明对应的权限)

        Car car = Car.createCar(this);        CarPropertyManager carProperty = (CarPropertyManager)car.getCarManager(Car.PROPERTY_SERVICE);        List carPropertyConfigList = carProperty.getPropertyList();

在来看看CarPropertyValue的成员变量列表

类型变量名说明
intmPropertyId属性ID
intmAreaId区域ID
intmStatus状态(0:可用;  1:不可用;  2:错误)
longmTimestamp时间戳(单位:纳秒)
TmValue当前值

举个例子 获取当前车速:

        Car car = Car.createCar(this);        CarPropertyManager carProperty = (CarPropertyManager)car.getCarManager(Car.PROPERTY_SERVICE);        //获取当前的车速        CarPropertyValue value = carProperty.getProperty(Float.class, VehiclePropertyIds.PERF_VEHICLE_SPEED,                VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);

来源地址:https://blog.csdn.net/u012514113/article/details/129841675

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯