汽车设置中的大多数页面都实现为一系列扩展 SettingsFragment
的片段,每个片段都在 CarSettingActivities
中定义了自己的 activity。这些静态 activity 扩展自 BaseCarSettingsActivity
。除了这些设置,您还可以从其他系统应用注入偏好设置,使其显示在汽车设置中。
在汽车设置中添加新偏好设置
要添加新设置,请执行以下操作:
- 定义 XML 文件
- 确保所有偏好设置都定义了
android:key
。preference_keys.xml
中维护了键的列表。偏好设置键应该是唯一的。 - 出于搜索索引编制目的,偏好设置屏幕也应定义
android:key
。preference_screen_keys.xml
中维护了偏好设置屏幕键的列表。偏好设置屏幕键也应该是唯一的。 - 如果偏好设置仅显示静态信息(例如,没有特殊的业务逻辑),请将偏好设置控制器设置为
com.android.car.settings.common.DefaultRestrictionsPreferenceController
。 - 如果偏好设置需要业务逻辑,请使用新的偏好设置控制器名称设置偏好设置控制器。
- 确保所有偏好设置都定义了
- (如果需要)在适当的软件包中创建偏好设置控制器,该控制器扩展
PreferenceController
。如果需要,请参阅 Javadoc。 - 创建一个片段,其中
getPreferenceScreenResId
返回步骤 1 中定义的 XML 文件。 - 在
CarSettingActivities
中创建一个 activity,该 activity 扩展BaseCarSettingsActivity
,然后实现getInitialFragment()
,返回步骤 3 中定义的片段。 - 更新
AndroidManifest.xml
以包含步骤 4 中定义的 activity。
示例
以下材料说明了此过程。
- 定义名为
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>
- 将偏好设置键添加到
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>
- 将偏好设置屏幕键添加到
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; } }
- 要创建片段,请替换
getPreferenceScreenResId
- 要保存新片段,请在
CarSettingActivities
中创建一个 activity - 使用新的 activity 更新清单文件
- 未直接在汽车设置应用中实现(例如,注入 OEM 实现的设置)。
- 应显示在汽车设置应用中。
- 要将 activity 标记为注入的设置,请向 activity 添加 intent 过滤器。
- 告知汽车设置应用它所属的类别。类别是一个常量,在
CategoryKey
中定义,用于指示注入的设置应显示在汽车设置的哪个级别。我们在CategoryKey
中提供了一组类别,但 OEM 定义自己的类别没有任何限制。 - (可选)在显示设置时添加摘要文本
<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>
public class DemoFragment extends SettingsFragment { @Override @XmlRes protected int getPreferenceScreenResId() { return R.xml.demo_fragment; } }
public class CarSettingActivities { [...] public static class DemoActivity extends BaseCarSettingsActivity { @Nullable @Override protected Fragment getInitialFragment() { return new DemoFragment(); } } }
<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设置项是注入的偏好设置。当以下任一条件为真时,注入的偏好设置特别有用。设置
要将 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>