Как добавить настройки автомобиля

Большинство страниц в настройках автомобиля реализованы как серия фрагментов, которые расширяют SettingsFragment. У каждого из них есть собственное действие, определенное в CarSettingActivities. Эти статические действия передаются из BaseCarSettingsActivity. Помимо этих настроек, вы можете добавить в CarSettings параметры из других системных приложений.

Как добавить новую настройку в меню "Настройки автомобиля"

Чтобы добавить новый параметр:

  1. Определите XML-файл:
    1. Убедитесь, что для всех параметров задано значение android:key. Список ключей хранится в preference_keys.xml. Ключи в разделе Preferences должны быть уникальными.
    2. Для индексирования в поиске экраны настроек должны иметь определенный android:key. Список ключей экрана настроек хранится в файле preference_screen_keys.xml. Ключи экранов настроек также должны быть уникальными.
    3. Если параметр отображает только статическую информацию (например, без специальной бизнес-логики), задайте для контроллера параметра значение com.android.car.settings.common.DefaultRestrictionsPreferenceController.
    4. Если для настройки требуется бизнес-логика, задайте контроллер настроек с новым названием.
  2. При необходимости создайте контроллер настроек в нужном пакете, который расширяет PreferenceController. При необходимости ознакомьтесь с документацией Javadoc.
  3. Создайте фрагмент с помощью getPreferenceScreenResId, возвращающий XML-файл, определенный на шаге 1.
  4. Создайте действие в CarSettingActivities, которое расширяет BaseCarSettingsActivity, а затем реализуйте getInitialFragment(), вернув фрагмент, определенный на шаге 3.
  5. Обновите AndroidManifest.xml, добавив действие, определенное на шаге 4.

Пример

Ниже приведены материалы, иллюстрирующие этот процесс.

  1. Определите XML-файл с названием demo_fragment.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:
  7. public class CarSettingActivities {
        [...]
        public static class DemoActivity extends BaseCarSettingsActivity {
            @Nullable
            @Override
            protected Fragment getInitialFragment() {
                return new DemoFragment();
            }
        }
    }
  8. Добавьте в файл манифеста новое действие:
  9. <application
        [...]
        <activity
            android:name=".common.CarSettingActivities$DemoActivity"
            android:exported="true">
            <meta-data android:name="distractionOptimized" android:value="true"/>
        </activity>
        [...]
    </application>

    Как добавить предпочтение внешнего намерения в настройках автомобиля

    Вместо того чтобы внедрять настройки, можно добавить их непосредственно в настройки автомобиля, используя намерение для перехода в другое приложение. Для этого нужно просто добавить настройку на экран настроек с действием намерения, которое разрешается во внешнее приложение. Как и другие настройки в настройках автомобиля, эти настройки имеют те же атрибуты 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. Например, элемент Google на главной странице настроек – это внедренная настройка. Внедренные настройки особенно полезны в следующих случаях: Настройка:

    • не реализован непосредственно в приложении CarSettings (например, не внедряет настройки, реализованные OEM-производителями).
    • Должен быть доступен в приложении CarSettings.

    Чтобы настроить действие как внедренный параметр, выполните следующие действия:

    1. Чтобы отметить объект activity как внедренную настройку, добавьте в него фильтр intent.
    2. Укажите, к какой категории относится приложение CarSettings. Категория – это константа, определенная в CategoryKey и указывающая, на каком уровне CarSettings должно появиться добавленное значение. Мы предоставляем набор категорий в CategoryKey, но производители устройств могут создавать собственные категории.
    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>

    Чтобы внедренная настройка появилась на определенной странице приложения CarSettings, добавьте в 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>