Per la maggior parte, l'aggiunta di riepiloghi delle preferenze è relativamente semplice, in quanto richiede solo l'aggiunta dell'attributo android:summary
alla rispettiva preferenza con la risorsa stringa appropriata. Tuttavia, se i sottotitoli devono aggiornarsi dinamicamente, potrebbe essere necessario un controller delle preferenze personalizzato.
Sottotitoli statici
Per aggiungere un sottotitolo statico a una preferenza:
- Aggiungi l'attributo
android:summary
alla preferenza. Ad esempio, per aggiungere un riepilogo alla preferenza delle impostazioni di visualizzazione L0, aggiungi qualcosa di simile a quanto segue agli attributi della preferenza:android:summary="@string/display_settings_summary"
Ad esempio, considera questo esempio di codice completo delle preferenze:
<Preference android:fragment="com.android.car.settings.display.DisplaySettingsFragment" android:icon="@drawable/ic_settings_display" android:key="@string/pk_display_settings_entry" android:title="@string/display_settings" android:summary="@string/display_settings_summary" settings:controller="com.android.car.settings.common.DefaultRestrictionsPreferenceController"/>
Sottotitoli dinamici
I sottotitoli codificati specificati con l'attributo android:summary
sono statici, pertanto non possono essere aggiornati in base a determinate condizioni. Per i sottotitoli dinamici, devi modificare il controllore delle preferenze per la preferenza. Il seguente esempio modifica la preferenza di posizione L0 in modo che abbia un sottotitolo che specifichi se la posizione è attiva o disattivata e, se attiva, indichi quante app attualmente hanno accesso alla posizione.
- Definisci le nuove stringhe:
<!-- Summary for Location settings when location is off [CHAR LIMIT=NONE] --> <string name="location_settings_summary_location_off">Off</string> <!-- Summary for Location settings when location is on, explaining how many apps have location permission [CHAR LIMIT=NONE]--> <plurals name="location_settings_summary_location_on"> <item quantity="one">On - <xliff:g id="count">%1$d</xliff:g> app has access to location</item> <item quantity="other">On - <xliff:g id="count">%1$d</xliff:g> apps have access to location</item> </plurals> <!-- Location settings, loading the number of apps which have location permission [CHAR LIMIT=30] --> <string name="location_settings_loading_app_permission_stats">Loading\u2026</string>
- Crea un nuovo PreferenceController,
LocationEntryPreferenceController
, per impostare e modificare dinamicamente il testo di riepilogo delle preferenze di geolocalizzazione:public class LocationEntryPreferenceController extends PreferenceController<Preference> { private static final Logger LOG = new Logger(LocationEntryPreferenceController.class); private static final IntentFilter INTENT_FILTER_LOCATION_MODE_CHANGED = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); private final Context mContext; private final LocationManager mLocationManager; /** Total number of apps that have location permissions. */ private int mNumTotal = -1; private int mNumTotalLoading = 0; private AtomicInteger mLoadingInProgress = new AtomicInteger(0); private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { refreshUi(); } }; public LocationEntryPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions) { super(context, preferenceKey, fragmentController, uxRestrictions); mContext = context; mLocationManager = (LocationManager) getContext().getSystemService( Service.LOCATION_SERVICE); } @Override protected Class<Preference> getPreferenceType() { return Preference.class; } @Override protected void onStartInternal() { getContext().registerReceiver(mReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED); } @Override protected void onStopInternal() { getContext().unregisterReceiver(mReceiver); } @Override protected void updateState(Preference preference) { super.updateState(preference); updateSummary(preference); if (!mLocationManager.isLocationEnabled() || mLoadingInProgress.get() != 0) { return; } mNumTotalLoading = 0; // Retrieve a list of users inside the current user profile group. List<UserHandle> users = mContext.getSystemService( UserManager.class).getUserProfiles(); mLoadingInProgress.set(users.size()); for (UserHandle user : users) { Context userContext = createPackageContextAsUser(mContext, user.getIdentifier()); if (userContext == null) { if (mLoadingInProgress.decrementAndGet() == 0) { setLocationAppCount(preference, mNumTotalLoading); } continue; } PermissionControllerManager permController = userContext.getSystemService(PermissionControllerManager.class); permController.countPermissionApps( Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED, (numApps) -> { mNumTotalLoading += numApps; if (mLoadingInProgress.decrementAndGet() == 0) { setLocationAppCount(preference, mNumTotalLoading); } }, null); } } @VisibleForTesting void setLocationAppCount(Preference preference, int numApps) { mNumTotal = numApps; updateSummary(preference); } private void updateSummary(Preference preference) { String summary = ""; if (mLocationManager.isLocationEnabled()) { if (mNumTotal == -1) { summary = mContext.getString(R.string.location_settings_loading_app_permission_stats); } else { summary = mContext.getResources().getQuantityString( R.plurals.location_settings_summary_location_on, mNumTotal, mNumTotal); } } else { summary = mContext.getString(R.string.location_settings_summary_location_off); } preference.setSummary(summary); } private Context createPackageContextAsUser(Context context, int userId) { try { return context.createPackageContextAsUser( context.getPackageName(), 0 /* flags */, UserHandle.of(userId)); } catch (PackageManager.NameNotFoundException e) { LOG.e("Failed to create user context", e); } return null; } }
Per questo controller di esempio:
- Se la posizione è disattivata, il testo del riepilogo viene impostato sulla stringa
location_settings_summary_location_off
. - Se la posizione è attivata, viene aggiunto il numero di app che dispongono dell'autorizzazione di accesso alla posizione. Durante
il caricamento, viene visualizzata la stringa
location_settings_loading_app_permission_stats
. Quando i dati vengono caricati, il controller imposta il riepilogo sulla stringalocation_settings_summary_location_on
con il numero di app con accesso specificato. - Quando il controller delle preferenze viene avviato, registra un ricevitore e aggiorna lo stato della preferenza quando cambia lo stato della posizione.
- Se la posizione è disattivata, il testo del riepilogo viene impostato sulla stringa
- Modifica il file XML del frammento per collegare il nuovo controller alla preferenza pertinente:
<Preference android:fragment="com.android.car.settings.location.LocationSettingsFragment" android:icon="@drawable/ic_settings_location" android:key="@string/pk_location_settings_entry" android:title="@string/location_settings_title" settings:controller="com.android.car.settings.location.LocationEntryPreferenceController"/>