目录

    • 前言
    • 开发环境
    • 1. Android Automotive 和 Android Auto的区别
      • Android Auto:
    • 2. Android Automotive 的驾驶模式介绍
    • 3. Android Automotive 实现驾驶模式的几种实现方式和代码示例
      • 方式一 .在Manifest文件中,使用在元数据meta-data对有可能造成分心驾驶的界面进行标记
      • 方式二 .使用CarDrivingStateManager类获取当前汽车的行驶状态,应用获取到行驶状态以后自己定义分心界面的遮挡方案
      • 方式三 .使用CarUxRestrictionsManager 并监听OnUxRestrictionsChangedListener
    • 结语

前言

最近在Android Automotive 上遇到的一些问题,有好几个都跟Android 车载操作系统上应用的驾驶模式有关,国内这方面的资料很少,自己在这里总结一下相关的知识,主要包含下面几个方面:
1. Android Automotive 和 Android Auto的区别
2. Android Automotive 的驾驶模式介绍
3. Android Automotive 实现驾驶模式的几种实现方式和代码示例,以及实现效果

主要是还是想总结一下Android 车载应用对Automotive 驾驶模式(Drive Mode)适配的几种方式。

Enjoy !

开发环境

Android Studio 版本4.1.2

1. Android Automotive 和 Android Auto的区别

Android Auto:

  1. Android Auto是一个专门为驾驶环境而设计的Android端App
  • 可以用来将Android设备上的部分功能,通过数据线映射到汽车的屏幕上。当时做Android Auto主打的是安全性,为了避免用户在驾驶过程中拿起手机,谷歌为Android Auto增加了Google Assistant,也就是在驾驶环境中使用语音交互,使得用户可以再不改变自身物理姿势的情况下实现一些手机app的操作。
  • 缺点是通过数据线将手机应用映射到车机上,应用到底还是在手机上运行的,以手机为中心,这样汽车本身相关数据,比如车速,GPS,传感器,行驶状态这些数据无法同步到手机上。
  1. Android Automotive 是可以再车载硬件上运行的操作系统和开源平台
    我们最常见的Android平台试运行在手机或者平板上的,和我们常见的Android 操作系统相比,Android Automotive具有相同的代码库,而且专门增加了对汽车特定的功能和技术支撑,主要包含下面几个方面:
  • Car App:包括OEM预装的,和第三方开发并且通过车载应用商店下载到车机上的app
  • Car API:OEM车厂提供给汽车App特有的接口,包括仪表盘相关的API,车辆硬件(座舱,通风等)的相关API,多媒体,导航,车载系统设置界面和车辆传感器相关的API
  • Car Service:Car Service是一个系统service,提供了和车相关的一系列的服务。
  • Vehicle Network Service:OEM厂商的网络服务
  • Vehicle HAL:汽车的硬件抽象层描述

Android Auto在车机上显示的其实是手机端的数据,Android Automotive则要考虑和手机端app的数据和账号同步的问题*

2. Android Automotive 的驾驶模式介绍

前面提到谷歌在2014年I/O 大会上推出Android Auto的初衷是更好地保障驾驶安全,Android Automotive 也增加了驾驶模式(Drive Mode),旨在帮助汽车OEM厂商从系统层面对有可能造成驾驶员分心的应用进行管理。
在驾驶模式下,Android Automotive会对Driving Distraction提出一系列的建议。OEM厂商也可以要求有可能造成驾驶员分心的 Activity 或者 Fragment 界面,在Manifest File中将自己注册成Distraction Optimized,比如需要驾驶员操作的登陆界面,扫码界面,切换歌曲,或者视频播放界面,游戏界面。而Android Automotive 则会在驾驶模式的时候,主动对标记为Distraction Optimized的界面进行限制。

3. Android Automotive 实现驾驶模式的几种实现方式和代码示例

方式一 .在Manifest文件中,使用在元数据meta-data对有可能造成分心驾驶的界面进行标记

Android Automotive 会把像下面这个使用元数据把distractionOptimized标记的活动或Fragment 标识为需要优化的界面,并且在驾驶模式时禁用这些界面,或者在当前Activity之上,增加UI 层级更高的提示框,从而避免在驾驶过程中这些界面造成用户分心。

        <activity android:name=".QRCodeScanPage">            <meta-data android:name="distractionOptimized" android:value="true"/>        </activity>

上面这段代码,用于给用户扫码登陆的界面QRCodeScanPage,在驾驶状态下会被AndroidAutomotive区别处理,OEM车厂也可以对Android Automotive进行客制化的修改,在限制界面之上增加遮盖。

大家可以看到,这种对分心界面的处理方式简单粗暴,直接在Manifest文件里对组件的元素增加Meta-data标签就可以了,缺点是不够灵活,所有的分心界面被遮盖以后效果都一样,而系统提供的统一遮盖方式,为了能够适用于各个应用的分心界面,往往直接把整个UI界面都挡住,即使QR码的UI很小,还是要盖住整个屏幕,用户体验很不好。

方式二 .使用CarDrivingStateManager类获取当前汽车的行驶状态,应用获取到行驶状态以后自己定义分心界面的遮挡方案

Android Automotive的CarDrivingStateManager类可以根据车辆硬件抽象层(VHAL)提供的传感器数据获取当前汽车的行驶状态(停车,空转,行驶),这样应用就可以通过下面的设置CarDrivingStateEventListener监听器:

导包:

import android.car.Car;/* For CarDrivingState */import android.car.drivingstate.CarDrivingStateEvent;import android.car.drivingstate.CarDrivingStateManager;
private final CarDrivingStateManager.CarDrivingStateEventListenermDrivingStateEventListener =       new CarDrivingStateManager.CarDrivingStateEventListener() {        @Override   public void onDrivingStateChanged(CarDrivingStateEvent event) {            mDrivingStateEvent = event;       handleDrivingStateChange();   }};

Android Automotive为 DrivingState定义了以下四个状态:

/** * This is when we don't have enough information to infer the car's driving state. */public static final int DRIVING_STATE_UNKNOWN = -1;/** * Car is parked - Gear is in Parked mode. */public static final int DRIVING_STATE_PARKED = 0;/** * Car is idling.  Gear is not in Parked mode and Speed of the vehicle is zero. */public static final int DRIVING_STATE_IDLING = 1;/** * Car is moving.  Gear is not in parked mode and speed of the vehicle is non zero. */public static final int DRIVING_STATE_MOVING = 2;

DrivingStateManager的代码:

mDrivingStateManager = (CarDrivingStateManager) mCar.getCarManager(       Car.CAR_DRIVING_STATE_SERVICE);/* Register the listener (implemented below) */mDrivingStateManager.registerListener(mDrivingStateEventListener);/* While we wait for a change to be notified, query the current state */mDrivingStateEvent = mDrivingStateManager.getCurrentCarDrivingState();

这样就可以获取当前车辆的三种行驶状态:停止,空转,驾驶,也可能会返回UNKNOWN,需要开发者处理。

另外,这里有个小窍门, 通过 CarUxRestrictions对象的isRequiresDistractionOptimization() 方法,可以直接获取当前车辆是否处于驾驶状态,1表示车辆处于驾驶状态,0表示非驾驶状态。

我们看到,上面的方法二可以主动查询当前车辆的行驶状态,然后可以根据DrivingStateEventListener返回的结果决定是否展示分心界面,也可以自己写遮盖代码。相比方式一,增加了很多灵活性。

方式三 .使用CarUxRestrictionsManager 并监听OnUxRestrictionsChangedListener

导包:

import android.car.Car;/* For CarUxRestrictions */import android.car.drivingstate.CarUxRestrictions;import android.car.drivingstate.CarUxRestrictionsManager;

从下面的CarUxRestrictionManager可以看到,OnUxRestrictionsChangedListener 提供了驾驶模式限制状态变化的监听:

@Nullable private CarUxRestrictionsManager mCarUxRestrictionsManager;private CarUxRestrictions mCurrentUxRestrictions;/* Implement the onUxRestrictionsChangedListener interface */private CarUxRestrictionsManager.OnUxRestrictionsChangedListener mUxrChangeListener =            new CarUxRestrictionsManager.OnUxRestrictionsChangedListener()    {             @Override        public void onUxRestrictionsChanged(CarUxRestrictions carUxRestrictions) {             mCurrentUxRestrictions = carUxRestrictions;        /* Handle the new restrictions */        handleUxRestrictionsChanged(carUxRestrictions);        }    };

这个方法三主要的应用场景是:不适于在启动时监听的分心事件或者持续时间比较长的分心界面。比如长时间的视频播放应用等等

结语

以上介绍了Android Automotive的驾驶模式,以及实现的几种方法,各个方式的优缺点和应用场景。明天膝盖关节镜手术,这里网不好,等回去了再把代码在Android 车载系统的虚拟机上实现出来,使用下面的ADB指令是可以模拟出当前车辆速度的,可以验证驾驶状态的改变,最后一个参数是速度,单位是米/秒。

adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 40

我的GitHub地址:https://github.com/18601949127
CSDN博客:https://blog.csdn.net/weixin_37734988

Bye!

更多相关文章

  1. Android——一个简单的银行系统
  2. Android——界面布局
  3. Android中要让一个程序的界面始终保持一个方向(禁止转屏)
  4. Android(安卓)实用工具Hierarchy Viewer实战
  5. 《Android(安卓)Dev Guide》系列教程
  6. 传智播客Android视频教程——第二天
  7. 修改Android解锁界面
  8. Android(安卓)实用工具Hierarchy Viewer实战
  9. Android(安卓)特殊界面效果之——透明界面

随机推荐

  1. Android接入腾讯OCR进行文字识别
  2. Android(安卓)View事件分发机制
  3. Graphics2D API:Paint类、Canvas类
  4. Android中SQLite使用
  5. APP测试的内容(一)
  6. Android(安卓)Bugly Tinker 热更新
  7. 安卓系统运行机制
  8. Android版本谷歌地图改版:屏幕下方增加一
  9. android集成popupwindow几种常见的效果
  10. Android(安卓)M 来了,和苹果iOS越来越像了