Android运行时权限Runtime Permission源码分析

这篇具有很好参考价值的文章主要介绍了Android运行时权限Runtime Permission源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Runtime Permission源码跟踪

Android 8.1.0

请求权限时弹窗代码

应用使用requestPermissions申请权限时,系统会弹出一个选择窗口,可进行允许。
grantpermissionsactivity,Android平台,android,java,ui

源码在packages/apps/PackageInstaller/文件下
GrantPermissionsActivity.java是进行权限分配的弹出窗口,通过GrantPermissionsDefaultViewHandler来控制GrantPermissionsActivity的ui视图,
按钮的点击事件是通过GrantPermissionsViewHandler.ResultListener接口来处理的,GrantPermissionsActivity实现了该接口

public class GrantPermissionsActivity extends OverlayTouchActivity
        implements GrantPermissionsViewHandler.ResultListener {
            mViewHandler = new com.android.packageinstaller.permission.ui.handheld
                    .GrantPermissionsViewHandlerImpl(this, getCallingPackage())
                    .setResultListener(this);
}

GrantPermissionsActivity.java
调用groupState.mGroup.grantRuntimePermissions获取权限,mGroup是AppPermissionGroup.java对象,grantRuntimePermissions实现过程后面会说。

先说下请求权限窗口中的UI,比如显示”要允许xx拔打电话和管理通话嘛“这条文本是
调用GrantPermissionsViewHandlerImpl的updateUi进行界面显示

    private boolean showNextPermissionGroupGrantRequest() {
        final int groupCount = mRequestGrantPermissionGroups.size();

        int currentIndex = 0;
        for (GroupState groupState : mRequestGrantPermissionGroups.values()) {
            if (groupState.mState == GroupState.STATE_UNKNOWN) {
                // 应用名称
                CharSequence appLabel = mAppPermissions.getAppLabel();
                
                // groupState.mGroup.getDescription()是权限对应的中文描述
                // 由AppPermissionGroup.java获取,比如“拨打电话和管理通话”
                // 注意就算请求的是一个子权限,但是获取到的将是子项对应的整个组
                // 比如申请android.permission.CALL_PHONE,允许后,会把它对应的整个电话组
                // 权限都获取到(包含拔打电话、读取通话记录、读取手机状态和身份、修改通话记录)
                Spanned message = Html.fromHtml(getString(R.string.permission_warning_template,
                        appLabel, groupState.mGroup.getDescription()), 0); 
                // Set the permission message as the title so it can be announced.
                setTitle(message);
                
                // 此updateUi会进行UI更新,比如请求权限的应用名,请求的权限对应名称,请求应用的应用图标等
                mViewHandler.updateUi(groupState.mGroup.getName(), groupCount, currentIndex,Icon.createWithResource(resources, icon), message,
                groupState.mGroup.isUserSet());
                //......
            }
        }
    }

mViewHandler对应类是GrantPermissionsViewHandlerImpl.java

mMessageView = (TextView) mCurrentDesc.findViewById(R.id.permission_message);

    private void updateDescription() { // 由updateUi调用
        mIconView.setImageDrawable(mGroupIcon.loadDrawable(mActivity));
        mMessageView.setText(mGroupMessage); // 比如显示“要允许xx拔打电话吗?”
    }

到此请求权限时弹窗代码已结束。

接下来说说设置中的应用权限窗口。

设置中应用权限窗口分析

设置–应用和通知–应用信息—xx应用—权限
grantpermissionsactivity,Android平台,android,java,ui
此窗口对应源码为
packages/apps/PackageInstaller/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java

// 设置的权限窗口中改变某应用的权限时,会触发此函数
public boolean onPreferenceChange(final Preference preference, Object newValue) {
// 只展试部分关键代码
     // key是权限,比如android.permission.CALL_PHONE
     PermissionInfo permInfo = pm.getPermissionInfo(key, 0);
     
     // AppPermissions mAppPermissions
     final AppPermissionGroup title_group
            = mAppPermissions.getPermissionGroup(permInfo.group);
    if (newValue == Boolean.TRUE) {
        title_group.grantRuntimePermissions(false, filterPermissions); // 取得权限
    } else {
        title_group.revokeRuntimePermissions(false, filterPermissions); // 取消权限
    }
}

上面的mAppPermissions是AppPermissions对象
title_group是AppPermissions.java代码中的mAppPermissions提供

请求权限弹窗与设置中权限UI请求权限都要用到AppPermissionGroup类,调用类中的grantRuntimePermissions函数。

AppPermissionGroup

packages/apps/PackageInstaller/src/com/android/packageinstaller/permission/model/AppPermissions.java

    // 在构造时在loadPermissionGroups初始化AppPermissionGroup数组
    public AppPermissions(Context context, PackageInfo packageInfo, String[] filterPermissions,
            boolean sortGroups, Runnable onErrorCallback) {
        mContext = context;
        mPackageInfo = packageInfo;
        mFilterPermissions = filterPermissions;
        mAppLabel = BidiFormatter.getInstance().unicodeWrap(
                packageInfo.applicationInfo.loadSafeLabel(
                context.getPackageManager()).toString());
        mSortGroups = sortGroups;
        mOnErrorCallback = onErrorCallback;
        loadPermissionGroups(); // 调用addPermissionGroupIfNeeded
    }

    private void addPermissionGroupIfNeeded(String permission) {
        if (getGroupForPermission(permission) != null) {
            return;
        }

        // AppPermissionGroup对应AppPermissionGroup.java
        AppPermissionGroup group = AppPermissionGroup.create(mContext,
                mPackageInfo, permission);
        if (group == null) {
            return;
        }

        mGroups.add(group);
    }

title_group对应AppPermissionGroup.java,AppPermissionGroup.grantRuntimePermissions此函数里面调用的是

private final PackageManager mPackageManager;
 mPackageManager.grantRuntimePermission(mPackageInfo.packageName,permission.getName(), mUserHandle);
 
 // 会跳到PackageManger中, 最终调用到PMS中
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
 ```java
     @Override
    public void grantRuntimePermission(String packageName, String name, final int userId) {
        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
    }

运行时权限获取的权限会通过private void writePermissionsSync(int userId)
更新到此文件中/data/system/users/0/runtime-permissions.xml
某应用,电话组权限未授权时如下

  <pkg name="com.android.sdk23ApiTest.wangyong">
    <item name="android.permission.READ_CALL_LOG" granted="false" flags="1" />
    <item name="android.permission.READ_PHONE_STATE" granted="false" flags="1" />
    <item name="android.permission.CALL_PHONE" granted="false" flags="1" />
    <item name="android.permission.WRITE_CALL_LOG" granted="false" flags="1" />
  </pkg>

允许电话组权限后变成这样

  <pkg name="com.android.sdk23ApiTest.wangyong">
    <item name="android.permission.READ_CALL_LOG" granted="true" flags="0" />
    <item name="android.permission.READ_PHONE_STATE" granted="true" flags="0" />
    <item name="android.permission.CALL_PHONE" granted="true" flags="0" />
    <item name="android.permission.WRITE_CALL_LOG" granted="true" flags="0" />
  </pkg>

Android 6以前的版本是保存在在data/system/packages.xml配置文件中,老版本代码就不分析了。
作者:帅得不敢出门 谢绝转载文章来源地址https://www.toymoban.com/news/detail-734852.html

到了这里,关于Android运行时权限Runtime Permission源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【flutter】使用permission_handler配置android和 iOS的权限

    flutter在pub.flutter-io.cn插件库中有很多的关于权限配置的插件,但是就我个人而言,比较推荐使用permission_handler这个插件。当我们打开permission_handler时候,往往新手小白会因为它的官网文档而弄的一头雾水,权限配置往往涉及到android和ios两个方向的相关知识,有可能大多数人就

    2024年02月12日
    浏览(11)
  • 【Android】android.permission.INTERACT_ACROSS_USERS_FULL是什么权限及其作用是什么

    android.permission.INTERACT_ACROSS_USERS_FULL 权限允许应用程序在所有用户之间进行交互。这包括在其他用户的应用程序中创建活动、发送广播和执行其他操作。 此权限仅适用于系统应用程序和具有特殊权限的应用程序。如果您需要此权限,请在您的应用程序的清单文件中声明它。 以

    2024年02月11日
    浏览(10)
  • jenkins运行pytest测试用例脚本报错:没有权限,无法写日志PermissionError:[Error 13]Permission denied

    jenkins运行pytest测试用例脚本报错:没有权限,无法写日志PermissionError:[Error 13]Permission denied

    报错信息: PermissionError:[Error 13]Permission denied:‘/var/jenkins_home/workspace/deleverySystem/Delivery_System/out_files/logs/waimai_20230823.log’ 解决方法: 在jenkins容器内部输入

    2024年02月11日
    浏览(44)
  • 关于android11,12权限问题Unable to decode stream: open failed: EACCES (Permission denied)

    第一次发博客 这个问题是我在制作一款app时发现的,我本来想在一个textview中加入一个图片 但是总是报错 E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20230129_123518.jpg: open failed: EACCES (Permission denied) 我在浏览了大多数关于这个问题的讨论和

    2024年02月07日
    浏览(43)
  • arcgis runtime for android 100.13.0 入门系列,一、初步引入与运行

    arcgis runtime for android 100.13.0 入门系列,一、初步引入与运行

    这是我来到csdn以来写的第一篇文章,希望能通过文字能把我的学习经过与心得分享给大家。我使用的是Kotlin来编写代码,我将默认各位具有一定的Android编程基础。言归正传,我们接下来要做的第一件事情就是使用AndroidStudio来创建一个空的新项目了 我接下来的操作都是遵循

    2023年04月17日
    浏览(12)
  • Android动态申请权限(运行时申请权限)

    Android动态申请权限(运行时申请权限)

    目录 1.需要动态申请权限的原因 2.Android权限动态申请 1.需要动态申请权限的原因   首先,Android权限分为大致两类,一类是普通权限,一类是危险权限,准确地讲其实还有一些特殊的权限,不过这些权限使用得相对较少,我们大致跳过.对于普通权限,系统会自动帮我们进行授权,由于

    2024年02月20日
    浏览(11)
  • 当我们尝试运行webpack-dev服务时,报node_modules/.bin/webpack-dev-server: Permission denied权限被拒绝要如何解决?

    当我们尝试运行webpack-dev服务时,报node_modules/.bin/webpack-dev-server: Permission denied权限被拒绝要如何解决?

    在尝试运行webpack-dev服务器时,我们似乎遇到了权限问题。当用户没有执行webpack dev-server脚本所需的权限时,通常会发生此错误。 要解决此问题,您可以尝试以下步骤: 1、检查权限:首先,确保您拥有执行webpack-dev-server脚本所需的权限。您可以通过在终端中运行以下命令来

    2024年04月17日
    浏览(14)
  • openxr runtime Monado 源码解析 源码分析:整体介绍 模块架构 模块作用 进程 线程模型 整体流程

    openxr runtime Monado 源码解析 源码分析:整体介绍 模块架构 模块作用 进程 线程模型 整体流程

    monado系列文章索引汇总: openxr runtime Monado 源码解析 源码分析:源码编译 准备工作说明 hello_xr解读 openxr runtime Monado 源码解析 源码分析:整体介绍 模块架构 模块作用 进程 线程模型 整体流程 openxr runtime Monado 源码解析 源码分析:CreateInstance流程(设备系统和合成器系统)C

    2024年02月11日
    浏览(14)
  • Android 设置后台运行权限

    Android 设置后台运行权限 在 Android 系统中,开发者可以为应用程序设置是否允许在后台持续运行的权限。这对于一些需要在后台进行长时间运算、网络连接或其他后台任务的应用程序来说非常重要。本文将介绍如何在 Android 应用程序中开启始终在后台运行的权限,并附上相应

    2024年02月05日
    浏览(11)
  • openxr runtime Monado 源码解析 源码分析:CreateSwapchain 画布 HardwareBuffer共享纹理 渲染线程 xrEndeFrame comp_renderer

    openxr runtime Monado 源码解析 源码分析:CreateSwapchain 画布 HardwareBuffer共享纹理 渲染线程 xrEndeFrame comp_renderer

    monado系列文章索引汇总: openxr runtime Monado 源码解析 源码分析:源码编译 准备工作说明 hello_xr解读 openxr runtime Monado 源码解析 源码分析:整体介绍 模块架构 模块作用 进程 线程模型 整体流程 openxr runtime Monado 源码解析 源码分析:CreateInstance流程(设备系统和合成器系统)C

    2024年02月05日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包