زیرنویس ترجیحی

در بیشتر موارد، افزودن خلاصه‌های ترجیحی نسبتاً ساده است زیرا فقط شامل افزودن ویژگی android:summary به اولویت مربوطه با منبع رشته مناسب است. با این حال، اگر زیرنویس ها باید به صورت پویا به روز شوند، ممکن است یک کنترل کننده ترجیحی سفارشی لازم باشد.

زیرنویس ثابت

برای افزودن یک زیرنویس ثابت به یک اولویت:

  1. ویژگی android:summary به اولویت اضافه کنید. به عنوان مثال، برای افزودن خلاصه ای به تنظیمات ترجیحی صفحه نمایش L0، چیزی شبیه به زیر را به ویژگی های ترجیحی اضافه کنید:
    android:summary="@string/display_settings_summary"
    

    به عنوان مثال، این نمونه کد ترجیحی کامل را در نظر بگیرید:

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

زیرنویس پویا

زیرنویس‌های مشخص‌شده با ویژگی android:summary ثابت هستند، بنابراین بر اساس شرایط خاص نمی‌توانند به‌روزرسانی شوند. برای زیرنویس‌های پویا، باید کنترل‌کننده ترجیحی را برای اولویت تغییر دهید. مثال زیر اولویت مکان L0 را تغییر می دهد تا یک زیرنویس داشته باشد که مشخص می کند مکان روشن یا خاموش است و در صورت روشن بودن، تعداد برنامه هایی که در حال حاضر به موقعیت مکانی دسترسی دارند را مشخص می کند.

  1. رشته های جدید را تعریف کنید:
    <!-- 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. یک PreferenceController جدید، LocationEntryPreferenceController ، برای تنظیم و تغییر پویا متن خلاصه برگزیده مکان ایجاد کنید:
    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;
        }
    }
    

    برای این کنترلر نمونه:

    • اگر مکان غیرفعال باشد، متن خلاصه بر روی رشته location_settings_summary_location_off تنظیم می شود.
    • اگر موقعیت مکانی فعال باشد، تعداد برنامه‌هایی که مجوز مکان دارند اضافه می‌شود. در حالی که این در حال بارگیری است، رشته location_settings_loading_app_permission_stats نشان داده می شود. هنگامی که داده ها بارگیری می شوند، کنترل کننده خلاصه را روی رشته location_settings_summary_location_on با تعداد برنامه های دارای دسترسی مشخص شده تنظیم می کند.
    • هنگامی که کنترل کننده ترجیحی راه اندازی می شود، کنترل کننده یک گیرنده را ثبت می کند و هنگامی که وضعیت مکان تغییر می کند، وضعیت ترجیحی را تازه می کند.
  3. فایل XML قطعه را تغییر دهید تا کنترلر جدید را به اولویت مربوطه متصل کنید:
    <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"/>