1.简介
简单学习下定位页面各项数据的获取逻辑
1.1.top_level_settings.xml
location相关的配置
<com.android.settings.widget.HomepagePreference
android:fragment="com.android.settings.location.LocationSettings"
android:icon="@drawable/ic_settings_location"
android:key="top_level_location"
android:order="-30"
android:title="@string/location_settings_title"
android:summary="@string/location_settings_loading_app_permission_stats"
settings:highlightableMenuKey="@string/menu_key_location"
settings:controller="com.android.settings.location.TopLevelLocationPreferenceController"/>
2.TopLevelLocationPreferenceController
2.1.getSummary
public CharSequence getSummary() {
if (mLocationManager.isLocationEnabled()) {
if (sSummary == null) {
//定位可用,默认显示loading...
sSummary = mContext.getString(
R.string.location_settings_loading_app_permission_stats);
}
return sSummary;
} else {
//定位不可用,显示off
return mContext.getString(R.string.location_settings_summary_location_off);
}
}
2.2.onStart
public void onStart() {
if (mReceiver == null) {
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
refreshLocationMode();
}
};
}
//监听mode的改变,刷新状态
mContext.registerReceiver(mReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED);
refreshLocationMode();
}
2.3.updateState
public void updateState(Preference preference) {
super.updateState(preference);
mPreference = preference;
//刷新summary,就是调用2.1的方法重新设置值
refreshSummary(preference);
//定位不可用,或者正在定位中,返回
if (!mLocationManager.isLocationEnabled() ||
loadingInProgress.get() != 0) {
return;
}
mNumTotalLoading = 0;
// Retrieve a list of users inside the current user profile group.
final List<UserHandle> users = mContext.getSystemService(
UserManager.class).getUserProfiles();
loadingInProgress.set(users.size());
for (UserHandle user : users) {
final Context userContext = Utils.createPackageContextAsUser(mContext,
user.getIdentifier());
if (userContext == null) {
if (loadingInProgress.decrementAndGet() == 0) {
setLocationAppCount(mNumTotalLoading);
}
continue;
}
final PermissionControllerManager permController =
userContext.getSystemService(PermissionControllerManager.class);
//获取申请定位的app个数
permController.countPermissionApps(
Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION),
PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED,
(numApps) -> {
mNumTotalLoading += numApps;
if (loadingInProgress.decrementAndGet() == 0) {
setLocationAppCount(mNumTotalLoading);
}
}, null);
}
}
>setLocationAppCount
void setLocationAppCount(int numApps) {
sSummary = mContext.getResources().getQuantityString(
R.plurals.location_settings_summary_location_on, numApps, numApps);
refreshSummary(mPreference);
}
2.4.plurals的用法
>1.定义
支持的quantity字段见补充4,就几个
<plurals name="book_number" >
<item quantity="one">%d book</item>
<item quantity="other">%d books</item>
</plurals>
>2.使用
第一个数字决定用哪个字符串,后边的数组用来替换占位符
getResources().getQuantityString(R.plurals.book_number,11,11)
>3.源码分析
public String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
throws NotFoundException {
//第一个数字获取字符串
String raw = getQuantityText(id, quantity).toString();
//然后替换后边的占位符
return String.format(mResourcesImpl.getConfiguration().getLocales().get(0), raw,
formatArgs);
}
//
public CharSequence getQuantityText(@PluralsRes int id, int quantity)
throws NotFoundException {
return mResourcesImpl.getQuantityText(id, quantity);
}
ResourcesImpl.java
public String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
throws NotFoundException {
String raw = getQuantityText(id, quantity).toString();
return String.format(mResourcesImpl.getConfiguration().getLocales().get(0), raw,
formatArgs);
}
//
CharSequence getQuantityText(@PluralsRes int id, int quantity) throws NotFoundException {
//获取规则
PluralRules rule = getPluralRule();
CharSequence res = mAssets.getResourceBagText(id,
attrForQuantityCode(rule.select(quantity)));
if (res != null) {
return res;
}
res = mAssets.getResourceBagText(id, ID_OTHER);
if (res != null) {
return res;
}
throw new NotFoundException("Plural resource ID #0x" + Integer.toHexString(id)
+ " quantity=" + quantity
+ " item=" + rule.select(quantity));
}
//往下看
private PluralRules getPluralRule() {
synchronized (sSync) {
if (mPluralRule == null) {
mPluralRule = PluralRules.forLocale(mConfiguration.getLocales().get(0));
}
return mPluralRule;
}
}
rule.select(quantity)返回一个string,然后匹配下边的。
private static int attrForQuantityCode(String quantityCode) {
switch (quantityCode) {
case PluralRules.KEYWORD_ZERO: return 0x01000005;
case PluralRules.KEYWORD_ONE: return 0x01000006;
case PluralRules.KEYWORD_TWO: return 0x01000007;
case PluralRules.KEYWORD_FEW: return 0x01000008;
case PluralRules.KEYWORD_MANY: return 0x01000009;
default: return ID_OTHER;
}
}
代码太多了,不看了,看下关键的算了。
>4.PluralRules
支持的keyword就这么几个
public static final String KEYWORD_FEW = "few";
public static final String KEYWORD_MANY = "many";
public static final String KEYWORD_ONE = "one";
public static final String KEYWORD_OTHER = "other";
public static final String KEYWORD_TWO = "two";
public static final String KEYWORD_ZERO = "zero";
>5.其他说明
源码里搜了一份plurals.xml文件,如下,这里就是规则的定义,全局搜了下,中文zh 只支持other,如下
<plurals type="cardinal">
<!-- For a canonicalized list, use GeneratedPluralSamples -->
<!-- 1: other -->
<pluralRules locales="bm bo dz hnj id ig ii in ja jbo jv jw kde kea km ko lkt lo ms my nqo osa root sah ses sg su th to tpi vi wo yo yue zh">
<pluralRule count="other"> @integer 0~15, 100, 1000, 10000, 100000, 1000000, … @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …</pluralRule>
</pluralRules>
<!-- 2: one,other -->
3.LocationSettings
3.1.location_settings.xml
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="location_settings"
android:title="@string/location_settings_title"
settings:keywords="@string/keywords_location">
<!--recent access ,里边数据是动态添加的-->
<PreferenceCategory
android:key="recent_location_access"
android:title="@string/location_category_recent_location_access"
settings:controller=
"com.android.settings.location.RecentLocationAccessPreferenceController"/>
<!--see all 按钮-->
<Preference
android:key="recent_location_access_see_all_button"
android:title="@string/location_recent_location_access_see_all"
android:icon="@drawable/ic_chevron_right_24dp"
android:fragment="com.android.settings.location.RecentLocationAccessSeeAllFragment"
settings:controller="com.android.settings.location.RecentLocationAccessSeeAllButtonPreferenceController"
settings:searchable="false"/>
<CheckBoxPreference
android:key="assisted_gps"
android:title="@string/assisted_gps"
android:summaryOn="@string/assisted_gps_enabled"
android:summaryOff="@string/assisted_gps_disabled"
settings:controller="com.android.settings.location.AgpsPreferenceController"/>
<PreferenceCategory
android:key="location_advanced_settings"
android:layout="@layout/preference_category_no_label">
<!-- This preference gets removed if there is no managed profile -->
<com.android.settingslib.RestrictedSwitchPreference
android:enabled="false"
android:key="managed_profile_location_switch"
android:selectable="true"
android:title="@string/managed_profile_location_switch_title"
settings:controller="com.android.settings.location.LocationForWorkPreferenceController"
settings:forWork="true"
settings:useAdminDisabledSummary="true"/>
<!-- This preference category gets removed if new_recent_location_ui is disabled -->
<!-- 图上all location permissions -->
<Preference
android:key="app_level_permissions"
android:title="@string/location_app_level_permissions"
settings:controller="com.android.settings.location.AppLocationPermissionPreferenceController">
<intent android:action="android.intent.action.MANAGE_PERMISSION_APPS">
<extra android:name="android.intent.extra.PERMISSION_NAME"
android:value="android.permission-group.LOCATION"/>
</intent>
</Preference>
<!--图上 location services-->
<Preference
android:fragment="com.android.settings.location.LocationServices"
android:key="location_services"
android:title="@string/location_services_preference_title"
settings:controller="com.android.settings.location.LocationServicesPreferenceController"/>
</PreferenceCategory>
<!--底部那提示文字-->
<com.android.settingslib.widget.FooterPreference
android:title="@string/location_settings_footer_general"
android:key="location_footer"
settings:searchable="false"
settings:controller="com.android.settings.location.LocationSettingsFooterPreferenceController"/>
</PreferenceScreen>
3.2.onActivityCreated
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final SettingsActivity activity = (SettingsActivity) getActivity();
//这个就是图上的use location开关
final SettingsMainSwitchBar switchBar = activity.getSwitchBar();
switchBar.setTitle(getContext().getString(R.string.location_settings_primary_switch_title));
switchBar.show();
mSwitchBarController = new LocationSwitchBarController(activity, switchBar,
getSettingsLifecycle());
//监听见3.3
mLocationEnabler = new LocationEnabler(getContext(), this, getSettingsLifecycle());
mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange) {
mController.updateShowSystem();
}
};
getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(
Settings.Secure.LOCATION_SHOW_SYSTEM_OPS), /* notifyForDescendants= */
false, mContentObserver);
}
>mController
mController = use(RecentLocationAccessPreferenceController.class);
3.3.onLocationModeChanged
其实就是定位开关关闭以后,recent的部分就隐藏了,这里监听enable的话,就滚动到recent的位置
public void onLocationModeChanged(int mode, boolean restricted) {
if (mLocationEnabler.isEnabled(mode)) {
scrollToPreference(RECENT_LOCATION_ACCESS_PREF_KEY);
}
}
4.LocationEnabler.java
4.1.onStart
注册一个广播监听MODE_CHANGED_ACTION,
static final IntentFilter INTENT_FILTER_LOCATION_MODE_CHANGED =
new IntentFilter(LocationManager.MODE_CHANGED_ACTION);
public void onStart() {
if (mReceiver == null) {
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
refreshLocationMode();
}
};
}
mContext.registerReceiver(mReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED);
refreshLocationMode();
}
>1.refreshLocationMode
获取定位模式,交给回调处理。回调是构造方法里传递过来的
public void refreshLocationMode() {
final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
if (mListener != null) {
mListener.onLocationModeChanged(mode, isRestricted());
}
}
>2.isRestricted
private boolean isRestricted() {
return mUserManager.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION);
}
4.2.setLocationEnabled
public void setLocationEnabled(boolean enabled) {
//先获取当前的定位模式
final int currentMode = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
if (isRestricted()) {
//受限用户,设置无效,返回旧的值
if (mListener != null) {
mListener.onLocationModeChanged(currentMode, true);
}
return;
}
updateLocationEnabled(mContext, enabled, UserHandle.myUserId(),
Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
refreshLocationMode();
}
5.Utils.java
com/android/settingslib/Utils.java
5.1.updateLocationEnabled
public static void updateLocationEnabled(Context context, boolean enabled, int userId,
int source) {
//记录下谁修改的定位模式
Settings.Secure.putIntForUser(
context.getContentResolver(), Settings.Secure.LOCATION_CHANGER, source,
userId);
LocationManager locationManager = context.getSystemService(LocationManager.class);
locationManager.setLocationEnabledForUser(enabled, UserHandle.of(userId));
}
>1.LOCATION_CHANGER
这个字段记录的是哪个app或者model修改了定位模式
public static final String LOCATION_CHANGER = "location_changer";
/**
* The location changer is unknown or unable to detect.
* @hide
*/
public static final int LOCATION_CHANGER_UNKNOWN = 0;
/**
* Location settings in system settings.
* @hide
*/
public static final int LOCATION_CHANGER_SYSTEM_SETTINGS = 1;
/**
* The location icon in drop down notification drawer.
* @hide
*/
public static final int LOCATION_CHANGER_QUICK_SETTINGS = 2;
>2.LocationManagerService.java
public void setLocationEnabledForUser(boolean enabled, int userId) {
userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, false, "setLocationEnabledForUser", null);
//权限检查
mContext.enforceCallingOrSelfPermission(WRITE_SECURE_SETTINGS, null);
//清除缓存
LocationManager.invalidateLocalLocationEnabledCaches();
//见6.1
mInjector.getSettingsHelper().setLocationEnabled(enabled, userId);
}
6.SystemSettingsHelper.java
6.1.setLocationEnabled
public void setLocationEnabled(boolean enabled, int userId) {
final long identity = Binder.clearCallingIdentity();
try {
Settings.Secure.putIntForUser(
mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE,
enabled
? Settings.Secure.LOCATION_MODE_ON
: Settings.Secure.LOCATION_MODE_OFF,
userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
>LOCATION_MODE
- 这个已经标记为废弃了
- 建议使用的LocationManager#isLocationEnabled()获取状态,MODE_CHANGED_ACTION监听广播
/**
* The current location mode of the device. Do not rely on this value being present or on
* ContentObserver notifications on the corresponding Uri.
*
* @deprecated The preferred methods for checking location mode and listening for changes
* are via {@link LocationManager#isLocationEnabled()} and
* {@link LocationManager#MODE_CHANGED_ACTION}.
*/
@Deprecated
@Readable
public static final String LOCATION_MODE = "location_mode";
/**
* Location mode is off.
*/
public static final int LOCATION_MODE_OFF = 0;
@Deprecated
public static final int LOCATION_MODE_SENSORS_ONLY = 1;
@Deprecated
public static final int LOCATION_MODE_BATTERY_SAVING = 2;
@Deprecated
public static final int LOCATION_MODE_HIGH_ACCURACY = 3;
@SystemApi
public static final int LOCATION_MODE_ON = LOCATION_MODE_HIGH_ACCURACY;
LocationManager里的获取,设置定位enable状态最终走的就是下边两个方法
6.2.isLocationEnabled
public boolean isLocationEnabled(int userId) {
return mLocationMode.getValueForUser(LOCATION_MODE_OFF, userId) != LOCATION_MODE_OFF;
}
6.3.setLocationEnabled
public void setLocationEnabled(boolean enabled, int userId) {
final long identity = Binder.clearCallingIdentity();
try {
Settings.Secure.putIntForUser(
mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE,
enabled
? Settings.Secure.LOCATION_MODE_ON
: Settings.Secure.LOCATION_MODE_OFF,
userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
7.LocationServices.java
7.1.location_services.xml
可以看到,里边默认有2个选项,其他数据通过controller来加载的
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="location_services"
android:title="@string/location_services_preference_title"
settings:controller="com.android.settings.location.LocationInjectedServicesPreferenceController">
<com.android.settingslib.RestrictedPreference
android:fragment="com.android.settings.location.WifiScanningFragment"
android:order="1000"
android:key="location_services_wifi_scanning"
android:title="@string/location_scanning_wifi_always_scanning_title"
settings:controller="com.android.settings.location.LocationServicesWifiScanningPreferenceController"/>
<com.android.settingslib.RestrictedPreference
android:fragment="com.android.settings.location.BluetoothScanningFragment"
android:order="1001"
android:key="location_services_bluetooth_scanning"
android:title="@string/location_scanning_bluetooth_always_scanning_title"
settings:controller="com.android.settings.location.LocationServicesBluetoothScanningPreferenceController"/>
</PreferenceScreen>
7.2.LocationInjectedServicesPreferenceController
public class LocationInjectedServicesPreferenceController
extends LocationInjectedServiceBasePreferenceController {
>1.injectLocationServices
protected void injectLocationServices(PreferenceScreen screen) {
final Map<Integer, List<Preference>> prefs = getLocationServices();
for (Map.Entry<Integer, List<Preference>> entry : prefs.entrySet()) {
for (Preference pref : entry.getValue()) {
if (pref instanceof RestrictedAppPreference) {
((RestrictedAppPreference) pref).checkRestrictionAndSetDisabled();
}
}
//只添加当前用户的
if (entry.getKey() == UserHandle.myUserId()) {
//按照title排序,添加到screen里
LocationSettings.addPreferencesSorted(entry.getValue(), screen);
}
}
}
后续都是父类的方法
>2.getLocationServices
protected Map<Integer, List<Preference>> getLocationServices() {
// If location access is locked down by device policy then we only show injected settings
// for the primary profile.
final int profileUserId = Utils.getManagedProfileId(mUserManager, UserHandle.myUserId());
return mInjector.getInjectedSettings(mFragment.getPreferenceManager().getContext(),
(profileUserId != UserHandle.USER_NULL
&& mLocationEnabler.getShareLocationEnforcedAdmin(profileUserId) != null)
? UserHandle.myUserId() : UserHandle.USER_CURRENT);
}
SettingsInjector.java
- 就是查找下边action的service信息,最后封装成了preference返回
protected List<InjectedSetting> getSettings(final UserHandle userHandle) {
PackageManager pm = mContext.getPackageManager();
// "android.location.SettingInjectorService"
Intent intent = new Intent(SettingInjectorService.ACTION_SERVICE_INTENT);
final int profileId = userHandle.getIdentifier();
List<ResolveInfo> resolveInfos =
pm.queryIntentServicesAsUser(intent, PackageManager.GET_META_DATA, profileId);
8.AppLocationPermissionPreferenceController.java
这个controller主要控制的就是summary的 2个变量,一个是是有定位权限的app数,一个是有定位权限已经被允许的app数
/** Total number of apps that has location permission. */
@VisibleForTesting
int mNumTotal = -1;
/** Total number of apps that has background location permission. */
@VisibleForTesting
int mNumHasLocation = -1;
8.1.getSummary
public CharSequence getSummary() {
if (mLocationManager.isLocationEnabled()) {
if (mNumTotal == -1 || mNumHasLocation == -1) {
//数据还未获取,显示loading
return mContext.getString(R.string.location_settings_loading_app_permission_stats);
}
//数据获取
return mContext.getResources().getQuantityString(
R.plurals.location_app_permission_summary_location_on, mNumHasLocation,
mNumHasLocation, mNumTotal);
} else {
//定位没有打开显示 Location is off
return mContext.getString(R.string.location_app_permission_summary_location_off);
}
}
8.2.updateState
public void updateState(Preference preference) {
super.updateState(preference);
mPreference = preference;
refreshSummary(preference);
// Bail out if location has been disabled, or there's another loading request in progress.
if (!mLocationManager.isLocationEnabled() ||
loadingInProgress.get() != 0) {
//定位不可用或者正在加载中
return;
}
mNumTotalLoading = 0;
mNumHasLocationLoading = 0;
// Retrieve a list of users inside the current user profile group.
final List<UserHandle> users = mContext.getSystemService(
UserManager.class).getUserProfiles();
loadingInProgress.set(2 * users.size());
for (UserHandle user : users) {
final Context userContext = Utils.createPackageContextAsUser(mContext,
user.getIdentifier());
if (userContext == null) {
for (int i = 0; i < 2; ++i) {
if (loadingInProgress.decrementAndGet() == 0) {
setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
}
}
continue;
}
final PermissionControllerManager permController =
userContext.getSystemService(PermissionControllerManager.class);
//权限管理器查找下边两个对应定位权限的app数
permController.countPermissionApps(
Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), 0,
(numApps) -> {
mNumTotalLoading += numApps;
if (loadingInProgress.decrementAndGet() == 0) {
setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
}
}, null);
//和上边一样的权限,只不过flag标记为定位权限已经被允许的数据才返回
permController.countPermissionApps(
Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION),
PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED,
(numApps) -> {
mNumHasLocationLoading += numApps;
if (loadingInProgress.decrementAndGet() == 0) {
setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
}
}, null);
}
}
9.RecentLocationAccessPreferenceController
9.1.loadRecentAccesses
public static final int MAX_APPS = 3;
private int mType = ProfileSelectFragment.ProfileType.ALL;
private void loadRecentAccesses() {
mCategoryRecentLocationRequests.removeAll();
final Context prefContext = mCategoryRecentLocationRequests.getContext();
final List<RecentAppOpsAccess.Access> recentLocationAccesses = new ArrayList<>();
final UserManager userManager = UserManager.get(mContext);
for (RecentAppOpsAccess.Access access : mRecentLocationApps.getAppListSorted(mShowSystem)) {
//见补充1
if (isRequestMatchesProfileType(userManager, access, mType)) {
recentLocationAccesses.add(access);
//最多添加3个
if (recentLocationAccesses.size() == MAX_APPS) {
break;
}
}
}
if (recentLocationAccesses.size() > 0) {
// Add preferences to container in original order (already sorted by recency).
//把数据转化为preference加入目录
for (RecentAppOpsAccess.Access access : recentLocationAccesses) {
mCategoryRecentLocationRequests.addPreference(
//见补充2
createAppPreference(prefContext, access, mFragment));
}
} else {
// If there's no item to display, add a "No recent apps" item.
//没有数据的话,添加一个"no recent apps"的选项
final Preference banner = new AppPreference(prefContext);
banner.setTitle(R.string.location_no_recent_accesses);
banner.setSelectable(false);
mCategoryRecentLocationRequests.addPreference(banner);
}
}
>1.isRequestMatchesProfileType
看type和当前用户是否匹配
public static boolean isRequestMatchesProfileType(UserManager userManager,
RecentAppOpsAccess.Access access, @ProfileSelectFragment.ProfileType int type) {
final boolean isWorkProfile = userManager.isManagedProfile(
access.userHandle.getIdentifier());
if (isWorkProfile && (type & ProfileSelectFragment.ProfileType.WORK) != 0) {
return true;
}
if (!isWorkProfile && (type & ProfileSelectFragment.ProfileType.PERSONAL) != 0) {
return true;
}
return false;
}
>2.createAppPreference
public static AppPreference createAppPreference(Context prefContext,
RecentAppOpsAccess.Access access, DashboardFragment fragment) {
final AppPreference pref = new AppPreference(prefContext);
pref.setIcon(access.icon);
pref.setTitle(access.label);
pref.setSummary(StringUtil.formatRelativeTime(prefContext,
System.currentTimeMillis() - access.accessFinishTime, false,
RelativeDateTimeFormatter.Style.SHORT));
pref.setOnPreferenceClickListener(new PackageEntryClickedListener(
fragment.getContext(), access.packageName, access.userHandle));
return pref;
}
新加选项的点击事件
public boolean onPreferenceClick(Preference preference) {
final Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, LOCATION);
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackage);
intent.putExtra(Intent.EXTRA_USER, mUserHandle);
mContext.startActivity(intent);
return true;
}
如下图跳转到对应app的定位权限控制页面了
9.2.displayPreference
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mCategoryRecentLocationRequests = screen.findPreference(getPreferenceKey());
mLocationEnabler.refreshLocationMode();
loadRecentAccesses();
}