Android系统编程入门系列之应用权限的定义与申请

2021年6月20日 4点热度 0条评论

在之前关于应用内数据本地保存为文件时,曾提到应用需要申请外部存储设备的读写权限才能访问外部存储中的文件。那么针对某一种权限,应用程序具体应该怎么申请使用呢?本文将详细介绍。

应用中的权限主要分为两类,分为正常权限和危险权限。在Android6.0即API 23之前,这两种权限均只需要在清单文件中声明即可,自Android6.0即API 23开始,危险权限不仅需要在清单文件中声明,还需要在代码使用该权限的界面Activity中动态申请,弹出权限申请框,由用户决定是否授权。应用所需要的权限列表及授权结果,可以从系统设置-应用管理-权限管理中查看。

这里对权限的分类与官网权限分类有所差异,为了便于理解,将官网的权限等级与本文中的权限分类对照关系绘制下表。

权限等级ProtectionLevel 本文权限分类
normal 正常权限
signature 正常权限
dangerous 危险权限
appop 正常权限

权限的相关设置,大多是在清单文件中配置的,只有在动态申请或增加附加权限与四大组件交互时需要在代码中配置。

如果应用程序如果需要使用某种权限,就必须在其清单文件中声明这些权限。

在清单文件中使用标签<uses-permission />,并为其属性android:name赋值,不同的权限分别定义了对应的字符串值。这些不同的权限可以从android.Manifest.permission权限类中查看。

从Android6.0即API 23开始,危险权限需要动态申请,并由用户主动授权后,才能继续执行获得授权后的操作,否则在未经授权时执行相关操作,程序运行时会抛出java.lang.SecurityException异常。

动态申请的权限,同样需要借助Context上下文环境对象来完成授权的相关操作。同时由于Android系统库的升级,下面涉及到的相关类,可以在老的系统支持库android.support.v4中找到,同样也可以在新版的androidx.core支持库中找到对应类。

动态申请权限,主要分为三个步骤,检查、请求、结果回调。

检查主要针对两个方向,一是检查应用程序是否已获得相关权限。调用ContextCompat.checkSelfPermission(Context context, String permission)静态方法,将上下文环境对象和相关权限的固定字符串分别作为参数传入即可。返回int类型的结果标注是否授权,其数值在android.content.pm.PackageManager类中以静态常量的形式分别定义了已授权的PERMISSION_GRANTED=0和未授权的PERMISSION_DENIED=-1

如果检查权限结果是已授权,那么可以执行获得该权限的后续操作。而当结果是未授权时,需要继续检查当前权限是否可向用户展示请求授权界面。调用ActivityCompat.shouldShowRequestPermissionRationale(android.app.Activity, java.lang.String)静态方法,参数activity是当前所在Activity界面对象,参数permission是相关权限字符串常量。返回boolean类型的结果,表示是否可正常展示请求授权界面。

如果检查展示请求授权界面结果失败,则需要提示用户相关权限无法正常授权,通常会提示用户可以到系统设置-权限管理中将该应用程序的相关权限打开,以正常执行应用程序获得授权后的操作。而当检查展示界面返回结果是true时,可以继续请求该权限。调用ActivityCompat.requestPermissions(Activity activity, String[] permissions, int requestCode)静态方法,参数activity是当前所在Activity界面对象,参数permissions是多个权限字符串组成的数组,参数requestCode是当前请求值,可任意定义,同时该值与请求结果返回时对应一致。

这里注意,在请求权限时必须要传入Activity界面对象,也就是说要想请求权限,必须通过应用程序的某个已处于正常运行状态的可视界面。而所谓的请求权限,与界面之间的互相启动有些相似,其本质都是一样的。

最后是请求结果的回调,在请求权限的Activity界面中,重写方法public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){}。在用户选择同意授权或拒绝授权后,由系统回调该方法。其中参数requestCode是请求值,与请求权限时的参数一致;参数permissions是相关的权限数组,同样与请求权限时的参数一致;参数grantResults是用户的授权结果,其数组索引与参数permissions中的索引一一对应,取值同样有表示已授权的PERMISSION_GRANTED=0和未授权的PERMISSION_DENIED=-1

在请求结果返回的所有权限均已授权后,边可以执行获得相关权限的后续操作。如果有未授权的权限,通常是执行异常操作,例如给用户相应提示并不再执行正常的后续操作。

另外,在检查权限相关操作返回如果某项权限在之前由用户选择拒绝授权并不再提示,

应用程序中对权限的使用方式在Android12之前可参考上述方式。那么具体系统提供了哪些权限,获得这些权限后可以做什么操作,这些问题将在后面的文章中介绍。