栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 动态权限申请过程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 动态权限申请过程

Android 动态权限申请过程 --Android12 1.申请

申请前提,manifest一定要有,没有是不会通过的。

动态申请代码:

    public final void requestPermissions(@NonNull String[] permissions, int requestCode) 

启动一个供用户选择的授权界面:

 final Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
        startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
        mHasCurrentPermissionsRequest = true;

创建intent的代码在PackageManager:

    public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {
        if (ArrayUtils.isEmpty(permissions)) {
           throw new IllegalArgumentException("permission cannot be null or empty");
        }
        Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);
        intent.putExtra(EXTRA_REQUEST_PERMISSIONS_NAMES, permissions);
        intent.setPackage(getPermissionControllerPackageName());
        return intent;
    }

包名获取的逻辑在pms里面:

private @NonNull String getRequiredPermissionControllerLPr() {
        final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);

        final List matches = queryIntentActivitiesInternal(intent, null,
                MATCH_SYSTEM_onLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                UserHandle.USER_SYSTEM);
        if (matches.size() == 1) {
            ResolveInfo resolveInfo = matches.get(0);
            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
                throw new RuntimeException("The permissions manager must be a privileged app");
            }
            return matches.get(0).getComponentInfo().packageName;
        } else {
            throw new RuntimeException("There must be exactly one permissions manager; found "
                    + matches);
        }
    }

这里注意下,获取的flag,然后就是获取的数量,必须是1,不是1直接异常,而且还是RuntimeException。
最后启动的参数就是:
pkg:com.android.permissioncontroller
action:android.content.pm.action.REQUEST_PERMISSIONS

那么启动的activity是哪个呢?
在源码位置是:

aosp/packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity
2.授予

上面界面启动以后,用户点击同意,兜兜转转最后到:
packageManager.grantRuntimePermission(group.packageName, perm.name, user)和 mPackageManager.updatePermissionFlags(String permName, String packageName,
int flagMask, int flagValues, UserHandle user)
最后的实现在:PermissionManagerService。
这里列出几个关键步骤,下面详细描述。
关键步骤:
1.READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE的处理逻辑。
这两个权限需要一些额外处理。主要是挂载什么的。

2.PermissionManagerService 里面有个默认的授权回调,在权限发生变化的时候会触发这个回调:private final PermissionCallback mDefaultPermissionCallback = new PermissionCallback();
然后调用:
mPackageManagerInt.writePermissionSettings(userIds, !sync); 这个就是写xml文件,表明app已经申请的权限,如果已经申请通过后面被关闭,这里也会有这一条,但是状态是false。

3.PermissionPolicyService 里面有注册一个动态权限变更的回调

这里需要注意下,这部分与Android11的有点不一样了。11在授权这里会计算gid变化,而且最后检测如果是读写sd卡相关,会直接通知 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName)。

PermissionPolicyService
 permissionManagerInternal.addonRuntimePermissionStateChangedListener(
            this::synchronizePackagePermissionsAndAppOpsAsyncForUser);

注册动态权限变更回调。

  final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser(
                getUserContext(getContext(), UserHandle.of(userId)));
        synchroniser.addPackage(pkg.packageName);
        final String[] sharedPkgNames = packageManagerInternal.getSharedUserPackagesForPackage(
                pkg.packageName, userId);

        for (String sharedPkgName : sharedPkgNames) {
            final AndroidPackage sharedPkg = packageManagerInternal
                    .getPackage(sharedPkgName);
            if (sharedPkg != null) {
                synchroniser.addPackage(sharedPkg.getPackageName());
            }
        }
        synchroniser.syncPackages();

shareUser都要处理。。。。

…未完待续

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/713489.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号