详解Android Automotive车载应用对驾驶模式Safe Drive Mode的适配
作者:谭妥 Tan Tuo 发布时间:2022-01-15 07:12:20
前言
最近在Android Automotive 上遇到的一些问题,有好几个都跟Android 车载操作系统上应用的驾驶模式有关,国内这方面的资料很少,自己在这里总结一下相关的知识,主要包含下面几个方面:
Android Automotive 和 Android Auto的区别
Android Automotive 的驾驶模式介绍
Android Automotive 实现驾驶模式的几种实现方式和代码示例,以及实现效果
主要是还是想总结一下Android 车载应用对Automotive 驾驶模式(Drive Mode)适配的几种方式。
开发环境
Android Studio 版本4.1.2
1. Android Automotive 和 Android Auto的区别
Android Auto:
Android Auto是一个专门为驾驶环境而设计的Android端App
可以用来将Android设备上的部分功能,通过数据线映射到汽车的屏幕上。当时做Android Auto主打的是安全性,为了避免用户在驾驶过程中拿起手机,谷歌为Android Auto增加了Google Assistant,也就是在驾驶环境中使用语音交互,使得用户可以再不改变自身物理姿势的情况下实现一些手机app的操作。
缺点是通过数据线将手机应用映射到车机上,应用到底还是在手机上运行的,以手机为中心,这样汽车本身相关数据,比如车速,GPS,传感器,行驶状态这些数据无法同步到手机上。
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.CarDrivingStateEventListener
mDrivingStateEventListener =
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);
}
};
这个方法三主要的应用场景是:不适于在启动时监听的分心事件或者持续时间比较长的分心界面。比如长时间的视频播放应用等等
adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 40
来源:https://blog.csdn.net/weixin_37734988/article/details/113470397
猜你喜欢
- 前言目前正在练手springboot+vue,因为很多步骤会遇到困难,当时查完资料解决,过一段时间就会忘记,所以决定建个系列记录下来。因为中
- 一、快捷键添加代码块:++快速生成属性等:++导包:+++自动创建变量名:++查找源代码:++按条件查找替换:++快速查看当前类的所有方法:
- 概述线上项目发布一般有以下几种方案:机发布蓝绿部署滚动部署灰度发布停机发布 这种发布一般在夜里或者进行大版本升级的时候发布,因为需要停机,所
- 读取自定义properties注入到bean在使用springboot项目时,可使用@value的方式直接读取application.pro
- 1、线性表定义线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特
- 问题:在项目中,当保存数据超过数据库字段列长度限制时,如何解决?一种常见的解决办法是:截串存取。顾名思义,就是对大文本数据按指定长度进行截取
- **正所谓,一入商城深似海~ 商城类的App,确实是有许多东西值得学习,但是只要略微斟酌一下,你又会发现,它们之间存在着许多不谋而合的相似,
- 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况
- 使用GroupingSearch对搜索结果进行分组Package org.apache.lucene.search.grouping Des
- 具体代码如下所示:import java.io.File;public class Scan { public static v
- 在项目中引入springcloud中的gateway时报以下错误Description:Parameter 0 of method modi
- Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的
- Map接口Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value;Map中的
- 当一个结合中想根据某一个字段做去重方法时使用以下代码IQueryable 继承自IEnumerable先举例:#region linq to
- 由于机器内存坏了,换了个内存,重新安装了一个64位的Fedora16,把原来的32位的Fedora15格掉了。于是在重新安装Android
- 一、简介在上篇 ElasticSearch 文章中,我们详细的介绍了 ElasticSearch 的各种 api 使用。实际的项目开发过程中
- pom.xml文件需要的内容<dependency> <groupId>re
- 今天安装了jdk1.8、tomcat8、和maven3.5.2,弄好后在myeclipse新建了一个maven项目,项目默认是jdk1.5,
- 题目给定count=0;让5个线程并发累加到1000;思路创建一个类MyRunnable,实现Runnable(继承Thread类也可)定义
- 相信大家对 String 和 StringBuffer 的区别也已经很了解了,但是估计还是会有很多同志对这两个类的工作原理有些不清楚的地方,