A maioria das páginas em "Configurações do carro" é implementada como uma série de
fragmentos que estendem SettingsFragment
,
cada um deles com a própria atividade definida em CarSettingActivities
.
Essas atividades estáticas são estendidas de BaseCarSettingsActivity
.
Além dessas configurações, é possível injetar preferências de outros apps do sistema para
que elas apareçam no CarSettings.
Adicionar 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 têm
android:key
definido. A lista de chaves é mantida empreference_keys.xml
. As chaves de preferências precisam ser exclusivas. - Para fins de indexação de pesquisa, as telas de preferência também precisam ter
um
android:key
definido. A lista de chaves da tela de preferência é mantida empreference_screen_keys.xml
. As chaves da tela de preferências também precisam ser exclusivas. - Se a preferência mostrar apenas informações estáticas (por exemplo,
sem uma lógica de negócios especial), defina o controlador de preferência como
com.android.car.settings.common.DefaultRestrictionsPreferenceController
. - Se a preferência exigir lógica de negócios, defina o controlador de preferência com um novo nome.
- Verifique se todas as preferências têm
- (Se necessário) Crie o controlador de preferência no pacote
adequado, que estende
PreferenceController
. Consulte o Javadoc, se necessário. - Crie um fragmento com
getPreferenceScreenResId
retornando o arquivo XML definido na Etapa 1. - Crie uma atividade em
CarSettingActivities
que estendaBaseCarSettingsActivity
e implementegetInitialFragment()
, retornando o fragmento definido na etapa 3. - Atualize
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 chave da tela de preferência a
preference_screen_keys.xml
:<resources> [...] <string name="psk_demo" translatable="false">demo_screen</string> </resources>
Para o 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 somente para os usuários administradores disponíveis. Para fazer 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 manter o novo fragmento, crie uma atividade em
CarSettingActivities
: - Atualize o arquivo de manifesto com a nova atividade:
- Não é implementado diretamente no app CarSettings, como injetar 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 à atividade.
- Informe ao app CarSettings a categoria a que ele pertence. A categoria é uma
constante, definida em
CategoryKey
, e é usada para indicar em qual nível de CarSettings a configuração injetada precisa aparecer. Fornecemos um conjunto de categorias emCategoryKey
, mas não há restrições para que os OEMs definam as 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>
Adicionar 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 nas configurações do carro que se destina a outro app. Isso pode ser feito simplesmente adicionando uma preferência a uma tela de preferência com uma ação de intent que é resolvida em um app externo. Como outras preferências nas 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 atividades externas ou internas. Por exemplo, o item de configuração Google na página inicial de Configurações é uma preferência injetada. As preferências injetadas são particularmente úteis quando uma das seguintes condições é verdadeira. A configuração:
Para configurar uma atividade como uma configuração injetada:
Para que a configuração injetada apareça em uma página específica no app CarSettings, inclua o seguinte código de exemplo no XML, modificando as 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>