添加汽车设置

汽车设置中的大多数页面都实现为一系列扩展 SettingsFragment 的片段,每个片段都在 CarSettingActivities 中定义了自己的 activity。这些静态 activity 扩展自 BaseCarSettingsActivity。除了这些设置,您还可以从其他系统应用注入偏好设置,使其显示在汽车设置中。

在汽车设置中添加新偏好设置

要添加新设置,请执行以下操作:

  1. 定义 XML 文件
    1. 确保所有偏好设置都定义了 android:keypreference_keys.xml 中维护了键的列表。偏好设置键应该是唯一的。
    2. 出于搜索索引编制目的,偏好设置屏幕也应定义 android:keypreference_screen_keys.xml 中维护了偏好设置屏幕键的列表。偏好设置屏幕键也应该是唯一的。
    3. 如果偏好设置仅显示静态信息(例如,没有特殊的业务逻辑),请将偏好设置控制器设置为 com.android.car.settings.common.DefaultRestrictionsPreferenceController
    4. 如果偏好设置需要业务逻辑,请使用新的偏好设置控制器名称设置偏好设置控制器。
  2. 如果需要)在适当的软件包中创建偏好设置控制器,该控制器扩展 PreferenceController。如果需要,请参阅 Javadoc。
  3. 创建一个片段,其中 getPreferenceScreenResId 返回步骤 1 中定义的 XML 文件。
  4. CarSettingActivities 中创建一个 activity,该 activity 扩展 BaseCarSettingsActivity,然后实现 getInitialFragment(),返回步骤 3 中定义的片段。
  5. 更新 AndroidManifest.xml 以包含步骤 4 中定义的 activity。

示例

以下材料说明了此过程。

  1. 定义名为 demo_fragment.xml 的 XML 文件
    <PreferenceScreen
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:settings="http://schemas.android.com/apk/res-auto"
        android:title="@string/demo_label"
        android:key="@string/psk_demo">
        <Preference
            android:icon="@drawable/ic_settings_demo_preference_1"
            android:key="@string/pk_demo_preference_1"
            android:title="@string/demo_preference_1_title"
    settings:controller="com.android.car.settings.common.DefaultRestrictionsPreferenceController">
            <intent android:targetPackage="com.android.car.settings"
    android:targetClass="com.android.car.settings.common.CarSettingActivities$DemoSetting1Activity"/>
        </Preference>
        <Preference
            android:icon="@drawable/ic_settings_demo_preference_2"
            android:key="@string/pk_demo_preference_2"
            android:title="@string/demo_preference_2_title"
    settings:controller="com.android.car.settings.example.MyCustomRestrictionsPreferenceController">
            <intent android:targetPackage="com.android.car.settings"
    android:targetClass="com.android.car.settings.common.CarSettingActivities$DemoSetting2Activity"/>
        </Preference>
    </PreferenceScreen>
  2. 将偏好设置键添加到 preference_keys
    <resources>
        [...]
        <string name="pk_demo_preference_1" translatable="false">demo_preference_1</string>
        <string name="pk_demo_preference_2" translatable="false">demo_preference_2</string>
    </resources>
  3. 将偏好设置屏幕键添加到 preference_screen_keys.xml
    <resources>
        [...]
        <string name="psk_demo" translatable="false">demo_screen</string>
    </resources>

    对于第一个示例偏好设置,使用 DefaultRestrictionsPreferenceController。对于第二个偏好设置,使用自定义偏好设置控制器,需要对其进行定义。对于此示例,您可以将此偏好设置自定义为适用于管理员用户。为此,请定义以下自定义控制器

    public class MyCustomRestrictionsPreferenceController extends 
        PreferenceController<Preference> {
    
        private final UserManager mUserManager;
    
        public MyCustomRestrictionsPreferenceController(Context context, String 
            preferenceKey, FragmentController fragmentController, 
            CarUxRestrictions uxRestrictions) {
            super(context, preferenceKey, fragmentController, uxRestrictions);
            mUserManager = UserManager.get(context);
        }
    
        @Override
        protected Class<Preference> getPreferenceType() {
            return Preference.class;
        }
    
        @Override
        public int getAvailabilityStatus() {
            return mUserManager.isAdminUser() ? AVAILABLE : DISABLED_FOR_USER;
        }
    }
  4. 要创建片段,请替换 getPreferenceScreenResId
  5. public class DemoFragment extends SettingsFragment {
    
        @Override
        @XmlRes
        protected int getPreferenceScreenResId() {
            return R.xml.demo_fragment;
        }
    }
  6. 要保存新片段,请在 CarSettingActivities 中创建一个 activity
  7. public class CarSettingActivities {
        [...]
        public static class DemoActivity extends BaseCarSettingsActivity {
            @Nullable
            @Override
            protected Fragment getInitialFragment() {
                return new DemoFragment();
            }
        }
    }
  8. 使用新的 activity 更新清单文件
  9. <application
        [...]
        <activity
            android:name=".common.CarSettingActivities$DemoActivity"
            android:exported="true">
            <meta-data android:name="distractionOptimized" android:value="true"/>
        </activity>
        [...]
    </application>

    在汽车设置中添加外部 intent 偏好设置

    除了注入的偏好设置之外,还可以将偏好设置直接插入到汽车设置中,该偏好设置会 intent 到另一个应用中。只需将偏好设置添加到具有 intent 操作的偏好设置屏幕即可完成此操作,该操作会解析为外部应用。与汽车设置中的其他偏好设置一样,这些偏好设置也具有相同的 XML 属性。

    <Preference
        android:key="@string/pk_demo_preference"
        android:title="@string/demo_preference_title"
        android:summary="@string/demo_preference_summary"
    settings:controller="com.android.car.settings.common.DefaultRestrictionsPreferenceController">
            <intent android:action="android.intent.action.DEMO_ACTION"/>
    </Preference>

    添加注入的偏好设置

    注入的偏好设置包含指向外部或内部 activity 的 intent。例如,设置主页上的Google设置项是注入的偏好设置。当以下任一条件为真时,注入的偏好设置特别有用。设置

    • 未直接在汽车设置应用中实现(例如,注入 OEM 实现的设置)。
    • 应显示在汽车设置应用中。

    要将 activity 配置为注入的设置,请执行以下操作:

    1. 要将 activity 标记为注入的设置,请向 activity 添加 intent 过滤器。
    2. 告知汽车设置应用它所属的类别。类别是一个常量,在 CategoryKey 中定义,用于指示注入的设置应显示在汽车设置的哪个级别。我们在 CategoryKey 中提供了一组类别,但 OEM 定义自己的类别没有任何限制。
    3. 可选)在显示设置时添加摘要文本
      <activity android:name="Settings$DemoSettingsActivity"
          <!-- Mark the activity as an injected setting -->
          <intent-filter>
              <action android:name="com.android.settings.action.EXTRA_SETTINGS"/>
          </intent-filter>
          <!-- Tell CarSettings app which category it belongs to -->
          <meta-data android:name="com.android.settings.category"
                     android:value="com.android.settings.category.demo_category"/>
          <!-- Tell CarSettings the what the preference title should be -->
          <meta-data android:name="com.android.settings.title"
                     android:value="@string/app_name" />
          <!-- Optional: specify the icon to show with the preference -->
          <meta-data android:name="com.android.settings.icon"
                     android:resource="@drawable/ic_demo"
                     android:value="true"/>
          <!-- Optional: Add a summary text when the string is displayed -->
          <meta-data android:name="com.android.settings.summary"
                     android:resource="@string/demo_summary"/>
      </activity>

    要在汽车设置应用中的特定页面上显示注入的设置,请在 XML 中包含以下示例代码,并在适当的位置修改变量

    <com.android.car.settings.common.LogicalPreferenceGroup
        <!-- Replace key string -->
        android:key="@string/pk_system_extra_settings"
        <!-- Indicates the preferences in the group should be injected in.
             ExtraSettingsPreferenceController contains the logic to pull in injected
             preferences. -->
    settings:controller="com.android.settings.common.ExtraSettingsPreferenceController">
        <!-- Tells the controller what activities should be pulled into this preference
             group. -->
        <intent android:action="com.android.settings.action.EXTRA_SETTINGS">
            <!-- Name and value should match the metadata in your activity -->
            <extra android:name="com.android.settings.category"
                   android:value="com.android.settings.category.demo_category"/>
        </intent>
    </com.android.car.settings.common.LogicalPreferenceGroup>