Bevorzugte Untertitel

In den meisten Fällen lassen sich Zusammenfassungen von Präferenzen relativ einfach hinzufügen, Dazu muss lediglich das Attribut android:summary der entsprechenden Einstellung hinzugefügt werden. durch die entsprechende Zeichenfolgenressource. Sollen die Untertitel jedoch dynamisch aktualisiert werden, ist unter Umständen ein Controller für benutzerdefinierte Einstellungen erforderlich.

Statische Untertitel

So fügst du einer Einstellung eine statische Unterüberschrift hinzu:

  1. Fügen Sie der Einstellung das Attribut android:summary hinzu. Um beispielsweise einen zu den Einstellungen des L0-Displays hinzu, fügen Sie Einstellungsattribute:
    android:summary="@string/display_settings_summary"
    

    Hier ein vollständiges Codebeispiel für Einstellungen:

    <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"/>
    

Dynamische Untertitel

Mit dem Attribut android:summary angegebene Untertitel sind statisch und können deshalb nicht unter bestimmten Bedingungen aktualisiert werden. Für dynamische Untertitel musst du die Einstellung ändern Controller für die Präferenz. Im folgenden Beispiel wird die L0-Standorteinstellung in sollten Sie einen Untertitel hinzufügen, der angibt, ob die Standortermittlung aktiviert oder deaktiviert ist, und gegebenenfalls angeben, wie viele Apps haben derzeit Standortzugriff.

  1. Definieren Sie die neuen Strings:
    <!-- 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>
    
  2. Erstellen Sie einen neuen PreferenceController (LocationEntryPreferenceController) für Sie können den Zusammenfassungstext der Standorteinstellungen dynamisch festlegen und ändern:
    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;
        }
    }
    

    Für diesen Beispiel-Controller:

    • Wenn der Standort deaktiviert ist, wird der Text der Zusammenfassung auf den location_settings_summary_location_off-String.
    • Wenn die Standortermittlung aktiviert ist, wird die Anzahl der Apps mit Berechtigung zur Standortermittlung hinzugefügt. Während wird der String location_settings_loading_app_permission_stats geladen, angezeigt. Wenn die Daten geladen sind, legt der Controller die Zusammenfassung auf den location_settings_summary_location_on-String mit der Anzahl der Apps mit Zugriffsrechte angegeben sind.
    • Wenn der bevorzugte Controller gestartet wird, registriert er einen Empfänger und aktualisiert den Einstellungsstatus, wenn sich der Standortstatus ändert.
  3. Ändere die XML-Fragmentdatei so, dass der neue Controller den entsprechenden Einstellungen zugeordnet wird:
    <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"/>