Google 致力于为黑人社区推动种族平等。查看具体举措

概览

我们为 Android Automotive OS (AAOS) 提供了汽车设置 (packages/apps/Car/Settings)。汽车设置与手机设置 (packages/apps/Settings) 不同。虽然汽车设置包含大家熟悉的一些手机设置,但提供的是车辆化的视觉界面,经过了防注意力分散优化,并且为原始设备制造商 (OEM) 提供很多自定义入口点。

除了下面介绍的汽车设置概览外,您还可以参考以下相关主题,详细了解汽车设置:

架构和准则

汽车设置中的大多数页面都是作为一系列扩展 SettingsFragment 的 fragment 实现的,每个 fragment 都在 CarSettingActivities 中定义自己的 activity。这些静态 Activity 从 BaseCarSettingsActivity 进行扩展。此规则有一些例外情况,例如某些特殊 fragment 从 BaseFragment 而非 SettingsFragment 进行扩展,而一些 activity 位于 CarSettingActivities 之外,这些都应该视为例外情况(并非要遵循的模式)。

静态偏好设置

静态偏好设置在 XML 中使用 PreferenceCarUiPreference 标记定义。SettingsFragment 实现使用 getPreferenceScreenResId() 方法定义哪个 XML 文件包含要显示的静态偏好设置列表。

动态偏好设置

动态偏好设置使用 PreferenceGroup> 标记或 PreferenceGroup 的实现(例如 LogicalPreferenceGroup)来定义一组通过偏好设置控制器生成和控制的偏好设置。

在汽车设置应用中,动态偏好设置表示一组常规偏好设置,可引导用户访问 CarSettings 中的其他页面,不过这些页面是通过偏好设置控制器添加的,而不是在 XML 中添加的。例如,“语言和输入偏好设置”下的“管理键盘偏好设置”基于系统是否允许使用这些输入法,将这些输入法动态添加到偏好设置页面。

操作栏

每个设置屏幕的顶部都有一个操作栏,其中可能包含“返回”导航、屏幕标题和辅助性操作微件(例如按钮和开关)。这些操作栏类似于 Android 提供的 ActionBar,但实际上属于自定义视图。在 Android 11 及更高版本中,此工具栏已纳入底盘基本布局中,该布局包含工具栏视图以及其余应用内容的帧布局。

辅助性操作微件是 MenuItem 类,应在相应 SettingsFragmentBaseFragmentonCreate 内创建。可见性、状态等属性应由 SettingsFragment 的业务逻辑中的 setter 进行控制。

// ExampleSettingsFragment.java
public class ExampleSettingsFragment extends SettingsFragment {

    @Override
    protected List<MenuItem> getToolbarMenuItems() {
        return Collections.singletonList(mClearConfirmButton);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mButton = new MenuItem.Builder(getContext())
                .setTitle(R.string.text)
                .setOnClickListener(mOnClickListener)
                .setUxRestrictions(CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP)
                .build();
    }

    private void updateState() {
        button.setVisible(false);
    }
}

操作栏支持汽车设置中的“防分心优化”。 创建时,在 MenuItem.Builder 中设置 UXRestrictions。

偏好设置控制器

每个设置页面都可以包含多个偏好设置。 为了帮助维护代码结构,每个偏好设置或相关偏好设置组均具有与之关联的 PreferenceController

有关这些组件之间的关系,请参阅下图:

CarSettings 组件

图 1. CarSettings 组件

PreferenceController 是一个具有生命周期感知能力的组件,有助于封装与特定偏好设置相关的业务逻辑。PreferenceControllers 只能通过 XML 附加到相关偏好设置。

// example_settings_fragment.xml
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:title="@string/example_settings_title">
  <Preference
    android:key="@string/pk_example_preference_key"
    android:title="@string/example_preference_title"
    settings:controller="com.android.car.settings.example.ExamplePreferenceController"/>
</PreferenceScreen>

汽车设置明确禁止通过代码创建 PreferenceController,以便您可以更轻松地修改设置层次结构,只需对 Java 代码做出极少的改动即可。

PreferenceController 可能需要一些动态数据才能正常运行。例如,用于关闭某个应用的通知的 PreferenceController 需要知道应该对哪个应用执行操作。由于 PreferenceControllers 始终在 XML 中定义,因此无法提供其他构造函数参数。这些附加值通过 PreferenceController 上的公共 setter 方法提供,并使用 SettingsFragment 中的 use(...) 方法进行设置。

// ExamplePreferenceController.java
public class ExamplePreferenceContorller extends PreferenceController<Preference> {

  private ExampleArg mExampleArg;

  public ExamplePreferenceController(...) {
    ...
  }

  public void setExampleArg(ExampleArg exampleArg) {
    mExampleArg = exampleArg;
  }
}

// ExampleSettingsFragment.java
public class ExampleSettingsFragment extends SettingsFragment {

  @Override
  @XmlRes
  protected int getPreferenceScreenResId() {
    Return R.xml.example_settings_fragment;
  }

  @Override
  public void onAttach(Context context) {
    ExampleArg arg = (ExampleArg) getArguments().getSerializeable(ARG_KEY);
    ExamplePreferenceController controller =
        use(ExamplePreferenceController.class, R.string.pk_example_preference_key);
    controller.setExampleArg(arg);
  }
}

使用 use(...) 方法的频率越高,以极少改动 Java 代码的方式重新安排设置层次结构的初始目标就越难实现,因为需要将现有 Fragment 代码的较大部分复制到新创建的 Fragment 中。有一种方法可以最大限度降低这样做的难度,那就是:

  • 尽量减少 use(...) 的使用。
  • 尝试每次都在 Fragment 中的某个位置(例如,在 onAttach() 方法中)调用 use(...)

Intent 处理

应由汽车设置应用处理的所有 intent 均在清单文件中定义。通常,intent 的定义和处理方式与大多数标准 Android 应用相同,但所有 activity 和 intent 过滤器均在清单中定义。

更改根 fragment

默认情况下,汽车设置会在应用启动时显示 HomepageFragment。可以通过反转 config_is_quick_settings_rootconfig_enable_home_settings_iconconfig_enable_quick_settings_icon 的布尔值将其配置为 QuickSettingFragment

如果需要,可使用 config_show_settings_root_exit_icon 显示或隐藏“退出”图标。

自定义主题

自定义其他属性和资源

汽车设置应用主要使用 CarSettingThemeTheme.CarUi 的扩展)。此主题用于对系统应用的外观和风格进行标准化,以确保整个系统的一致性。

自定义偏好设置

自定义偏好设置涵盖以下附加位置:

  • 某些基本偏好设置类的布局在 car_preference 中定义,并针对汽车 build 进行叠加。此处可替换为基本偏好设置类的任何自定义布局。
  • 汽车设置使用主要在 common 软件包中定义的自定义偏好设置。这些设置应在汽车设置模块中独立于基本偏好设置类进行叠加。