A maioria das páginas em Car Settings são implementadas como uma série de fragmentos que estendem SettingsFragment
, com cada uma delas tendo sua própria atividade definida em CarSettingActivities
. Essas atividades estáticas são estendidas de BaseCarSettingsActivity
. Além dessas configurações, você pode injetar preferências de outros aplicativos do sistema para que apareçam em CarSettings.
Adicionando uma nova preferência nas configurações do carro
Para adicionar uma nova configuração:
- Defina um arquivo XML:
- Certifique-se de que todas as preferências tenham definido
android:key
. A lista de chaves é mantida empreference_keys.xml
. As chaves de preferências devem 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
. As teclas de tela de preferência também devem ser exclusivas. - Se a preferência exibir apenas informações estáticas (por exemplo, nenhuma 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, configure o controlador de preferência com um novo nome de controlador de preferência.
- Certifique-se de que todas as preferências tenham definido
- ( Se necessário ) Crie o controlador de preferência no pacote apropriado, que estende
PreferenceController
. Veja 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 então 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 de tela de preferência a
preference_screen_keys.xml
:<resources> [...] <string name="psk_demo" translatable="false">demo_screen</string> </resources>
Para a primeira preferência de exemplo, use
DefaultRestrictionsPreferenceController
. Para a segunda preferência, use um controlador de preferência personalizado, que precisa ser definido. Para este exemplo, você pode personalizar essa preferência apenas para 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 aplicativo CarSettings (como injetar uma configuração implementada por OEMs).
- Deve aparecer no aplicativo CarSettings.
- Para marcar a atividade como uma configuração injetada, adicione um filtro de intenção à atividade.
- Diga ao aplicativo CarSettings a qual categoria ele pertence. A categoria é uma constante, definida em
CategoryKey
, e é usada para indicar em qual nível de CarSettings a configuração injetada deve aparecer. Fornecemos um conjunto de categorias dentro deCategoryKey
, mas não há restrições para OEMs definirem suas próprias categorias. - ( opcional ) Adicione 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>
Adicionando uma preferência de intenção 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 aplicativo. Isso pode ser feito simplesmente adicionando uma preferência a uma tela de preferências com uma ação de intenção que resolva para um aplicativo externo. Como outras preferências nas configurações do carro, essas preferências têm os mesmos atributos XML disponíveis para elas.
<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>
Adicionando uma preferência injetada
As preferências injetadas contêm intenções que levam a atividades externas ou internas. Por exemplo, o item de configuração do Google na página inicial de Configurações é uma preferência injetada. As preferências injetadas são particularmente úteis quando qualquer um dos itens a seguir for verdadeiro. 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 aplicativo 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>