A maioria das páginas em "Configurações do carro" é implementada como uma série de
fragmentos que estendem SettingsFragment
,
com cada um com a própria atividade definida em CarSettingActivities
.
Essas atividades estáticas são estendidas do BaseCarSettingsActivity
.
Além dessas configurações, é possível injetar preferências de outros aplicativos do sistema para
aparecem em CarSettings.
Adicione uma nova preferência nas Configurações do carro
Para adicionar uma nova configuração:
- Defina um arquivo XML:
- Verifique se todas as preferências definiram
android:key
. A lista de chaves é mantida empreference_keys.xml
. Preferências chaves precisam ser exclusivas. - Para fins de indexação de pesquisa, as telas de preferência também devem ter
um
android:key
definido. A lista de teclas de tela de preferência é mantida empreference_screen_keys.xml
. Preferência as teclas de tela também precisam ser exclusivas. - Se a preferência exibir somente informações estáticas (por exemplo,
nenhuma lógica de negócios especial), defina o controlador de preferências como
com.android.car.settings.common.DefaultRestrictionsPreferenceController
: - Se a preferência exigir lógica de negócios, defina a preferência com um novo nome para o controlador de preferências.
- Verifique se todas as preferências definiram
- (Se necessário) Crie o controlador de preferências no
que estende
PreferenceController
. Consulte o Javadoc, se necessário. - Crie um fragmento com
getPreferenceScreenResId
retornando o Arquivo XML definido na Etapa 1. - Criar uma atividade no app
CarSettingActivities
que se estendeBaseCarSettingsActivity
e implementargetInitialFragment()
, retornando o fragmento definido na Etapa 3. - Atualize o
AndroidManifest.xml
para incluir a atividade definida na Etapa 4.
Exemplo
O material a seguir ilustra esse processo.
- Defina um arquivo XML chamado
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>
- Adicione as chaves de preferência a
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>
- Adicione a tecla de tela de preferência a
preference_screen_keys.xml
:<resources> [...] <string name="psk_demo" translatable="false">demo_screen</string> </resources>
No primeiro exemplo de preferência, use
DefaultRestrictionsPreferenceController
. Para a segunda preferência, use um controlador de preferências personalizado, que precisa ser definido. Neste exemplo, você pode personalizar essa preferência apenas para os usuários administradores disponíveis. Para isso, defina o seguinte controlador personalizado: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; } }
- Para criar um fragmento, substitua
getPreferenceScreenResId
: - Para armazenar o novo fragmento, crie uma atividade em
CarSettingActivities
: - Atualize o arquivo de manifesto com a nova atividade:
- não seja implementado diretamente no app CarSettings (como injetando uma configuração implementada por OEMs).
- Deve aparecer no app CarSettings.
- Para marcar a atividade como uma configuração injetada, adicione um filtro de intent ao a atividade.
- Informe ao app CarSettings a que categoria ele pertence. A categoria é uma
constante, definida em
CategoryKey
, e é usada para indicar em que nível de CarSettings a configuração injetada deve aparecer. Fornecemos um conjunto de categoriasCategoryKey
, mas não há restrições para os OEMs definirem em suas próprias categorias. - (opcional) Adicione um texto de resumo quando a configuração for exibida:
<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>
Adicione uma preferência de intent externa nas Configurações do carro
Como alternativa às preferências injetadas, também é possível inserir uma preferência diretamente em "Configurações do carro" que tenta outro app. Para isso, basta adicionar uma preferência para uma tela de preferências com uma ação de intent que se resolve para uma tela app. Assim como outras preferências em "Configurações do carro", essas preferências têm os mesmos atributos XML disponíveis.
<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>
Adicionar uma preferência injetada
As preferências injetadas contêm intents que levam a interações atividades. Por exemplo, o item de configuração Google na guia "Configurações" é uma preferência injetada. As preferências injetadas são particularmente será útil quando uma das seguintes condições for verdadeira. A configuração:
Para definir uma atividade como uma configuração injetada:
Para que a configuração injetada apareça em uma página específica no CarSettings, inclua o exemplo de código abaixo no XML, modificando variáveis, quando apropriado:
<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>