上篇博客说到AndroidQ预置APP赋予默认权限,但是只能对于targetSDKversion 23 版本以上的APP才会生效,调查了问题,做出以下的修改可以对23 版本以下的APP生效。
废话少说直接上代码:
代码位置:
alps\frameworks\base\services\core\java\com\android\server\pm\permission
类名:DefaultPermissionGrantPolicy.java
在上篇博客添加权限的基础上修改:
grantDefaultSystemHandlerPermissions() 函数内添加申请权限代码:
//Webkey Test
String WebTest = "com.webkey";
grantPermissionsToPackage(WebTest, userId, false, true, ALWAYS_LOCATION_PERMISSIONS);
grantPermissionsToPackage(WebTest, userId, false, true, STORAGE_PERMISSIONS);
添加之后进入函数:grantPermissionsToPackage(),对于参数就不多废话了,按照上面的参数添加进来就ok(后面的权限自己填写,由于AndroidQ接收的是permissionGroups,可以把多个权限写在一起,这个大家自己尝试吧)
之后函数里调用了grantPermissionsToPackage(getPackageInfo(packageName), userId, false /* systemFixed */, ignoreSystemPackage, whitelistRestrictedPermissions, permissionGroups); 函数,进入函数体,函数内调用 grantRuntimePermissions() 函数,继续计入函数体,这个函数内就有了对于低版本SDK的判断,代码:
if (applicationInfo != null
&& applicationInfo.targetSdkVersion < splitPerm.getTargetSdk()
&& permissionsWithoutSplits.contains(splitPerm.getSplitPermission())) {
permissions.addAll(splitPerm.getNewPermissions());
}
把这个代码直接干掉, 到这里就解决了 预置系统级APP sdk低于23 不给默认权限的办法。
如果还有问题那就把↓
final List<PermissionManager.SplitPermissionInfo> splitPermissions =
mContext.getSystemService(PermissionManager.class).getSplitPermissions();
final int numSplitPerms = splitPermissions.size();
这行代码也干掉。
上面把预置为系统级APP的低版本问题解决,预置非系统级的APP 赋予默认权限还有几步,找到
alps\frameworks\base\services\core\java\com\android\server\pm\permission\PermissionManagerService.java
这个位置,然后定位到这个判断方法:
// Keep track of app op permissions.
if (bp.isAppOp()) {
mSettings.addAppOpPackage(perm, pkg.packageName);
}
if (bp.isNormal()) {
// For all apps normal permissions are install time ones.
grant = GRANT_INSTALL;
} else if (bp.isRuntime()) {
if (origPermissions.hasInstallPermission(bp.getName())
|| upgradedActivityRecognitionPermission != null) {
// Before Q we represented some runtime permissions as install permissions,
// in Q we cannot do this anymore. Hence upgrade them all.
//grant = GRANT_UPGRADE;
grant = GRANT_INSTALL;
} else {
// For modern apps keep runtime permissions unchanged.
//grant = GRANT_RUNTIME;
grant = GRANT_INSTALL;
}
} else if (bp.isSignature()) {
// For all apps signature permissions are install time ones.
allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
if (allowedSig) {
grant = GRANT_INSTALL;
}
}
上面代码我已经注释改完了,就是把 //grant = GRANT_UPGRADE; 和 //grant = GRANT_RUNTIME; 改为 grant = GRANT_INSTALL;
为什么这么改呢?具体看注释去吧。 还有一点要注意,如果只改:
else {
// For modern apps keep runtime permissions unchanged.
//grant = GRANT_RUNTIME;
grant = GRANT_INSTALL;
}
这个代码块中的代码的话,刷机之后首次开机时会赋予权限, 但是重启机器的话权限就会消失,所以呢如果想保持权限一直存在就要上面的代码块也要改。
if (origPermissions.hasInstallPermission(bp.getName())
|| upgradedActivityRecognitionPermission != null) {
// Before Q we represented some runtime permissions as install permissions,
// in Q we cannot do this anymore. Hence upgrade them all.
//grant = GRANT_UPGRADE;
grant = GRANT_INSTALL;
}
以上就是需要注意的地方。
/** Permission grant: not grant the permission. */
private static final int GRANT_DENIED = 1;
/** Permission grant: grant the permission as an install permission. */
private static final int GRANT_INSTALL = 2;
/** Permission grant: grant the permission as a runtime one. */
private static final int GRANT_RUNTIME = 3;
/** Permission grant: grant as runtime a permission that was granted as an install time one. */
private static final int GRANT_UPGRADE = 4;
参数说明,都有注释我就不废话了,自己看注释吧。