实现系统界面

Android Automotive 提供了专为车辆开发的全新系统界面。该系统界面的大部分组件都与框架服务紧密耦合。系统界面是指屏幕上显示的任何不属于应用的元素。Automotive 系统界面(在 CarSystemUI 元素包中)是 Android 系统界面(在系统界面包中)的一个扩展程序,专为车辆定制。

什么是系统界面?

Automotive 系统界面的专用组件包括:

组件 说明
锁屏界面 用户通过该屏幕为特定用户账号验证身份。
导航栏 一种系统栏,可以位于屏幕的左侧、底部或右侧,并且可以包含用于导航到不同应用、切换“通知”面板以及提供车辆控制(例如 HVAC)的属性按钮。它与 Android 系统界面实现不同,后者提供的是返回按钮、主屏幕按钮和应用堆栈按钮。
状态栏 一种系统栏,沿屏幕一侧放置,用作导航栏。状态栏还提供支持以下各项内容的功能:
  • 连接图标。包括蓝牙、Wi-Fi 和热点/移动网络连接。
  • 下拉“通知”面板。例如,从屏幕顶部向下滑动。
  • 浮动通知 (HUN)。
系统界面 指屏幕上显示的任何不属于应用的元素。
用户切换器界面 用户可通过该屏幕选择其他用户。
音量界面 司机使用实体音量按钮改变设备音量时显示的对话框。

系统界面的工作原理

系统界面是设备开机时运行的 Android 应用。该应用通过 SystemServer 的反射启动。下面列出了与系统界面的用户可见切面最相关的入口点。使用这些组件可针对 Automotive 特定功能自定义 Android 系统界面。

  • config_statusBarComponent
  • config_systemUIFactoryComponent

CarSystemUI 是系统界面包的一个扩展程序,这意味着 CarSystemUI 包可以使用并替换系统界面包中的类和资源。

自定义系统界面

叠加层

虽然可以通过修改 Android 源代码来自定义系统界面,但这样做会使应用未来 Android 更新的过程变得更加困难和复杂。Android 支持使用叠加层目录,让您无需修改源代码即可替换资源文件。在 Android 构建系统中,叠加层系统会以可控方式替换文件,无需遍历整个 AOSP 源代码树,即可清楚标识所有已修改的文件。

叠加层文件必须放在 PRODUCT_PACKAGE_OVERLAYS 目录中,并且必须与原始 AOSP 根结构具有完全相同的子文件夹。对于 Android 10 或更高版本,PRODUCT_PACKAGE_OVERLAYS 设置为:

PRODUCT_PACKAGE_OVERLAYS := packages/services/Car/car_product/overlay

Automotive 系统界面使用系统界面和 CarSystemUI 包中的资源,这意味着,可以通过使用叠加层替换每个位置的资源以影响 Automotive 系统界面的外观。

如需替换文件,请在您指定的 /overlay 目录中复制要替换的文件的目录结构,然后将替换文件添加到该目录中。例如,如需替换:

frameworks/base/packages/CarSystemUI/res/layout/super_status_bar.xml

请添加以下目录中的 super_status_bar.xml 替换文件:

packages/services/Car/car_product/overlay/frameworks/base/packages/CarSystemUI/res/layout/

如需替换 frameworks/base/packages/SystemUI/res/values/config.xml(在系统界面中,而不是在 CarSystemUI 中),请将 config.xml 替换文件添加到以下目录中:

packages/services/Car/car_product/overlay/frameworks/base/packages/SystemUI/res/layout/

packages/services/Car/car_product/overlay/frameworks/base/packages/CarSystemUI/res/layout/

下面将介绍两个主要自定义入口点。

Automotive 系统界面可以有三个导航栏,分别放置在屏幕的左侧、底部和右侧。通过以下配置可分别切换显示每个导航栏:

  • config_enableLeftSystemBar
  • config_enableBottomSystemBar
  • config_enableRightSystemBar

每个导航栏都有预配和取消预配状态,可以通过叠加相应的布局文件来自定义该状态:

  • car_left_system_bar.xml
  • car_left_system_bar_unprovisioned.xml
  • car_system_bar.xml (底部导航栏的布局)
  • car_system_bar_unprovisioned.xml
  • car_right_system_bar.xml
  • car_right_system_bar_unprovisioned.xml

这些布局必须在顶层包含 com.android.systemui.car.systembar.CarSystemBarView,该视图可以包含任何其他必要的视图。可以使用 com.android.systemui.car.systembar.CarSystemBarButton 在导航栏中添加按钮。

如果为指定用户正确预配了设备,这些视图将在 CarSystemBar#createSystemBar 中膨胀。

状态栏

您可以将状态栏视为包含附加功能的导航栏。与导航栏不同的是,状态栏没有停用标志。您可以使用以下文件修改状态栏:

  • car_top_navigation_bar.xml
  • car_top_navigation_bar_unprovisioned.xml

这些布局必须在顶层包含 com.android.systemui.statusbar.car.CarNavigationBarView。状态栏包含状态图标。如需更改图标尺寸,请按缩放比例统一缩放图标,而不是指定具体尺寸。例如,在叠加层文件 /overlay/frameworks/base/packages/CarSystemUI/res/values/dimens.xml 中,添加以下维度可使图标增大一倍:

<resources>
    <!-- The amount by which to scale up the status bar icons.-->
    <item name="status_bar_icon_scale_factor" format="float" type="dimen">2</item>
</resources>

状态栏位于特殊的窗口层中,该窗口层还包含“通知”面板、用户切换器、浮动通知 (HUN) 和 Keyguard。这些组件的各种布局包含在 super_status_bar.xml 中。

系统界面源代码更改

叠加层可能无法提供充分自定义系统界面行为所需的灵活性。

提醒:对 Android 源代码所做的更改难以在后续版本的 Android 中更新。我们强烈建议您扩展 Automotive 系统界面代码,而不是直接修改代码。这样就可以在合并冲突极少的情况下升级 Automotive 系统界面底层源代码,因为所有自定义项都是通过已知的 API 接口实现的。

您可以通过以下两个入口点自定义系统界面的大多数切面:

  • config_statusBarComponent
  • config_systemUIFactoryComponent

例如,如果您创建一个名为 com.android.systemui.statusbar.car.custom.CustomCarStatusBar 的类(扩展自 CarStatusBar),请将 config_statusBarComponent 更新为指向此新组件。通过扩展此类,可自定义与系统栏和通知逻辑相关的大多数元素。

同样,您可以创建 CustomCarSystemUIFactory 并将其放在 config_systemUIFactoryComponent 中。使用此类可更新 VolumeUI 和锁屏的功能。

自定义用户切换和解锁

以下材料介绍了如何自定义用户切换体验。

术语 说明
Keyguard 用于防止与前台应用意外互动的全屏对话框。 可在设置了多个用户时,保护每个用户的隐私。
“正在加载”对话框 切换用户时显示的“正在加载”屏幕。
锁屏、Bouncer 要求用户输入 PIN 码、密码或绘制解锁图案的屏幕。
用户 Android 用户。
用户选择器 设备启动时显示的用户选择器屏幕。
用户切换器 通过快捷设置切换屏幕时显示的用户切换器。

自定义用户切换

Keyguard 和 Bouncer

在 Android Automotive OS 中,仅当用户点击锁屏上的“取消”按钮时,才会显示带有用户选择器的 Keyguard 屏幕。Keyguard 屏幕如下所示。

Keyguard 屏幕

图 1. Keyguard 屏幕

在用户选择用于解锁设备的隐私设置类型后,系统会显示带有 Bouncer 的锁屏,如下所示。

锁屏

图 2. 锁屏。

将锁设置为手动触发开机或关机时,请使用以下指令:

adb shell input keyevent 26

用户选择器

如果某个设备是车载系统界面状态栏和地图不可或缺的一部分,那么当该设备重新启动时,系统就会显示用户选择器屏幕。如需了解详情,请参阅 FullscreenUserSwitcher

“正在加载”屏幕

图 3. 用户选择器界面

可以在 car_fullscreen_user_switcher.xml 中自定义此屏幕的布局。

“正在加载”屏幕

无论使用哪个入口点,切换用户时都会显示“正在加载”屏幕。例如,通过用户选择器或“设置”屏幕切换用户时。“正在加载”屏幕是框架系统界面不可或缺的一部分,它映射到名为 CarUserSwitchingDialog 的公共类。有关示例,请参阅上面的图 3。

可以使用 Theme_DeviceDefault_Light_Dialog_Alert_UserSwitchingDialog 自定义主题。

为了设置 Android 用户,初始设置向导流程允许司机自行设置用户名。如果司机随后将该 Android 用户与某个 Google 账号关联,那么,系统会从该账号中选择用户名。但是,如果司机指定了一个名称(例如 DriverB),之后将该用户名与其 Google 账号的名称 Maddy 关联,那么,最初分配的名称 (DriverB) 不会发生变化,因为系统已显式设置该名称。司机只能在“设置”菜单中更改该名称。

可以在 car_user_switching_dialog.xml. 中自定义布局

原始设备制造商 (OEM) 可以使用名为 NoActionBar.Fullscreen 的主题隐藏状态栏和导航栏。(这是原始系统界面,已针对车载参考界面进行更新。)如需了解详情,请参阅自定义

OEM 可以提供界面入口点来切换用户,但结果有时可能不尽如人意。如发生该情况,则:

  1. 原始设备制造商 (OEM) 会创建并显示自定义的“正在加载”屏幕(或对话框)。
    • (特定于用户体验)当用户选择切换方式时,原始设备制造商 (OEM) 会启动自定义的“正在加载”屏幕,该屏幕可能会在用户切换完成后隐藏。
    • 原始设备制造商 (OEM) 必须根据自己的偏好设置优先窗口。例如,设置为优先级较高的窗口类型。该屏幕的优先级不能超过 Keyguard。
  2. OEM 按 config_customuserswitchui 中所述,在核心框架 config.xml 中设置 config_customUserSwitchUi=true。因此,该框架不显示 CarUserSwitchingDialog

自定义锁屏

锁屏是系统界面不可或缺的一部分,可由 OEM 自定义。如需自定义该流程,请从 frameworks/base/packages/CarSystemUI/ 开始。

自定义首次用户设置

设置向导会执行首次用户设置。该流程也可自定义。您可以使用 UserManager API 创建用户。在某些情况下,这可以在后台实现,从而简化设置向导流程。