先上图,看看最终我们可以得到什么样子的结果:

android获取应用内自定义权限与权限使用情况_第1张图片

截图来自 android开发工具箱, 点我下载 android开发工具箱

 

应用内权限信息分为两个部分,我们先来看应用内权限使用情况。

PackageManager pm = context.getPackageManager();PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);if (packageInfo.requestedPermissions != null) {    for (String permission : packageInfo.requestedPermissions) {        PermissionInfo permissionInfo = pm.getPermissionInfo(permission, 0);        if ((permissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0                            || (permissionInfo.flags & FLAG_REMOVED) != 0) {            continue;        }        boolean isHasPermission = PackageManager.PERMISSION_GRANTED == pm.checkPermission(permission, packageName);        ...    }}

获取权限列表步骤大致为:

1. 先从PackageInfo获取应用内使用权限的列表,得到一个String数组
2. 遍历数组,使用PackageManager获取PermissionInfo对象
3. 根据permissionInfo.flags对结果进行筛选
4. 判断应用是否已经获得了此权限

这样,我们的列表所需的数据就齐了。下面我们看看PermissionInfo里面都有些什么我们需要的信息

public class PermissionInfo extends PackageItemInfo implements Parcelable {    public int protectionLevel;    public @Nullable String group;    public @Flags int flags;    //获取权限描述信息    public @Nullable CharSequence loadDescription(@NonNull PackageManager pm) {        ...    }}

我们使用上面的信息即可获取权限的level、group、权限的描述。flags是之前我们用到的属性。

系统没有提供给我们把int类型的protectionLevel转换成String的方法,但是,PermissionInfo类中有个隐藏的方法:

/** @hide */@UnsupportedAppUsagepublic static @NonNull String protectionToString(int level) {    String protLevel = "????";    switch (level & PROTECTION_MASK_BASE) {        case PermissionInfo.PROTECTION_DANGEROUS:            protLevel = "dangerous";            break;        case PermissionInfo.PROTECTION_NORMAL:            protLevel = "normal";            break;        case PermissionInfo.PROTECTION_SIGNATURE:            protLevel = "signature";            break;        case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:            protLevel = "signatureOrSystem";            break;    }    ...}

这里不但隐藏了,还加了UnsupportedAppUsage注解,所以只能复制出来一份了。同时,这段代码也给出了判断一个权限是否是危险权限的方法:

public static boolean isDangerous(int level) {    return (level & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS;}

系统没有直接提供获取权限描述的属性,但是提供了方法loadDescription,最后来看一下group。

group的概念是android6引入运行时权限引入了,但是到了android10,应用无法在界面中查询权限的分组方式。所以我们在不同版本上获取group信息会有所不同。

下面以`android.permission.ACCESS_FINE_LOCATION`权限为例。

在android6-9上面,我们获取到的group内容为:

android.permission-group.LOCATION

在android10上面获取到的group内容为:

> android.permission-group.UNDEFINED

综上,显示应用内使用的权限的几个关键信息:权限名称、级别、分组以及权限描述就都有了。

自定义权限要要更简单一点

if (packageInfo.permissions != null) {    for (PermissionInfo permissionInfo : packageInfo.permissions) {        boolean isHasPermission = PackageManager.PERMISSION_GRANTED == pm.checkPermission(permissionInfo.name, packageName);        ...    }}

packageInfo.permissions是PermissionInfo数组,所以少了使用PackageManager获取PermissionInfo对象这一步,其余逻辑与展示系统权限逻辑完全一致,至此,我们就能制作一个展示应用内权限的页面了。

 

点我下载 android开发工具箱

更多相关文章

  1. 【android 权限】
  2. Android获取SDK的版本信息
  3. 获取android联系人信息
  4. Android 存储用户信息
  5. android 获取 imei号码以及其他信息

随机推荐

  1. 详解Android提交数据到服务器的两种方式
  2. 自定义MediaPlayer控制组件
  3. Android(安卓)同时setTag两次保存多种值
  4. Kotlin For Android介绍
  5. 关于 Android(安卓)Drawable Resource学
  6. Android(安卓)进程间通讯之通过Intent+bu
  7. Service通过Broadcast更新UI
  8. Android(安卓)Path类
  9. Android快速开发框架ZBLibrary源码分享
  10. [Android]资源存储方法