防分心优化 (DO) 是一种工具,旨在减少驾驶员在汽车行驶过程中与“设置”应用的交互。驾驶员在汽车行驶过程中可能需要更改某些设置,因此该应用没有被彻底屏蔽。但默认情况下,大多数偏好设置都处于停用状态,只有重要且易于更新的偏好设置处于启用状态。
图 1. 汽车行驶过程中处于启用状态的应用
如果所有 activity 均未经过防分心优化,也可以将其全部屏蔽,如下所示。该方法目前主要用于设置搜索。
图 2. 屏蔽所有 Activity
您可以通过配置叠加层对 DO 性能进行基本的自定义。如果需要进行更细化的自定义,可通过代码执行更多更改。
高级自定义
如果某个偏好设置在汽车行驶过程中处于停用状态,点按该偏好设置后,系统会显示一个消息框,提示驾驶员该偏好设置在汽车行驶过程中不可用,但前提是该偏好设置附加了偏好设置控制器。该消息使用的是 restricted_while_driving
字符串,可通过叠加层对其进行自定义(前提是该字符串的长度少于 60 个字符)。
图 3. 自定义的叠加层
可使用 config_always_ignore_ux_restrictions
来停用整个 DO 框架。将其设置为 true 表示驾驶员可以与“设置”应用的各项功能交互。
<bool name="config_always_ignore_ux_restrictions">true</bool>
如果将其设置为 false,“设置”应用将回退到
config_ignore_ux_restrictions
来确定哪些偏好设置应在汽车行驶过程中处于启用状态。此处提供的字符串应指向 preference_keys.xml.
中定义的字符串
示例
为展示如何在汽车行驶过程中启用深层嵌套的设置,本示例演示了如何启用文字转语音 (TTS) 输出设置。要实现这一点,需要将层次结构中的所有设置都添加到 config_ignore_ux_restrictions
中。其中包括系统、语言和输入法以及配置的 TTS 偏好设置,因为我们的层次结构是“系统”->“语言和输入法”->“文字转语音 (TTS) 输出”。不过,文字转语音 Fragment 中的偏好设置仍处于停用状态。要使其处于启用状态,需要为相应偏好设置添加键。在本示例中,我们要启用“播放”偏好设置,但不启用引擎偏好设置,因此会在配置中添加 pk_tts_playback_group
。
<string-array name="config_ignore_ux_restrictions"> [...] <item>@string/pk_system_settings_entry</item> <item>@string/pk_languages_and_input_settings</item> <item>@string/pk_tts_settings_entry</item> <item>@string/pk_tts_playback_group</item> </string-array>
细化的自定义
某些偏好设置可能还需要比根据汽车行驶状态启用/停用某项偏好设置自定义程度更高的行为。例如,蓝牙和 Wi-Fi 经过了修改,可以在驾车时显示已保存的蓝牙设备或 Wi-Fi 接入点。
目前无法通过基于配置的解决方案来进行此类调整。不过,您可以创建一个可扩展 PreferenceController 并替换 onApplyUxRestrictions()
的自定义类,以进行所需的更改。
创建自定义偏好设置控制器后,您可以叠加相关的 XML 文件,从而将默认的偏好设置控制器替换为您自己的实现。
示例
CarSettings 中的某些偏好设置具有这种自定义程度更高的行为,进一步自定义时可以之为例。例如,对于 WLAN 接入点列表,我们希望在汽车行驶过程中仅显示所保存的接入点(隐藏其他接入点)。要实现这一点,请使用以下代码:
} else if (shouldApplyUxRestrictions(getUxRestrictions())) { wifiEntries = getCarWifiManager().getSavedWifiEntries(); } else { wifiEntries = getCarWifiManager().getAllWifiEntries(); }
列表中显示的接入点已受到限制,因此无需再为这些偏好设置应用 UxRestrictions
。而是替换 onApplyUxRestrictions
并故意执行空操作:
@Override protected void onApplyUxRestrictions(CarUxRestrictions uxRestrictions) { // Since the list dynamically changes based on the UX restrictions, we // enable this fragment regardless of the restriction. Intentional no-op. }
绑定蓝牙的设备中提供了另一个示例。如果您希望继续支持连接和断开蓝牙设备,但停用这些设备的其他访问权限。要实现这一点,可再次替换 onApplyUxRestrictions
,但此时如果已启用 NO_SETUP
限制,则隐藏针对相应偏好设置的次要操作。
@Override protected void onApplyUxRestrictions(CarUxRestrictions uxRestrictions) { super.onApplyUxRestrictions(uxRestrictions); if (CarUxRestrictionsHelper.isNoSetup(uxRestrictions)) { updateActionVisibility(getPreference(), /* isActionVisible= */ false); } }