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

应用中的权限主要分为两类,分为正常权限和危险权限。在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之前可参考上述方式。那么具体系统提供了哪些权限,获得这些权限后可以做什么操作,这些问题将在后面的文章中介绍。

Android系统编程入门系列之应用权限的定义与申请的更多相关文章

  1. Android系统编程入门系列之加载界面Activity

    上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...

  2. Android系统编程入门系列之应用环境及开发环境介绍

        作为移动端操作系统,目前最新的Android 11.0已经发展的比较完善了,现在也到了系统的整理一番的时间,接下来的系列文章将以Android开发者为中心,争取用归纳总结的态度对初级入门者所应 ...

  3. Android系统编程入门系列之应用数据文件化保存

    应用中关于数据的持久化保存,不管是简单的SharedPreferences还是数据库SQLiteDatabase,本质上都是将数据保存到系统的某种类型的文件中.因此可以直接使用java.io.File ...

  4. Android系统编程入门系列之硬件交互——传感器

    到目前为止,关于应用程序与用户之间的相关内容便比较肤浅的大致介绍完毕.而在整个系统架构中,应用程序与用户之间的交互,犹如参天大树上的枝干和树叶,交互起来五彩缤纷,但使整个生态系统保持生命力的核心,在于 ...

  5. Android系统编程入门系列之硬件交互——通信硬件Bluetooth

    通信硬件NFC的文章,虽然可以在Android系统中通过非直接接触的形式与支持NFC硬件的设备通信,但是也只能交互一些简短的标签内容,对大量的持续性数据,却并不能很好的支持.因此针对这个弊端,可以考虑 ...

  6. Android系统编程入门系列之硬件交互——无线通信WLAN

    Android系统的移动设备大多支持无线WLAN技术.利用该技术,不仅能实现互联网通信,还能实现无线定位,热点共享等远程通信功能.针对使用WLAN的不同功能,可能需要分别申请不同的权限声明,同时调用不 ...

  7. Android系统编程入门系列之清单文件

    在上一篇文章中已经提到,Android系统加载应用程序之后,首先会读取该应用程序的AndroidManifest.xml清单文件,之后根据该清单文件加载后边的东西.所以要开发应用程序,自然要先知道清单 ...

  8. Android系统编程入门系列之界面Activity绘制展示

    上篇文章介绍了界面Activity的启动方式和生命周期,本篇将继续介绍在界面Activity中的内容是如何绘制展示给用户的. 在Android系统上运行新创建的界面Activtiy,给用户展示的是空白 ...

  9. Android系统编程入门系列之界面Activity交互响应

    在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...

随机推荐

  1. Django——实现最基础的评论功能(只有一级评论)

    我对评论功能的理解: --------(1)数据库建一个评论的表 --------(2)前端建一个提交评论的form表单 --------(3)表单提交评论内容后写入到数据库评论表中 -------- ...

  2. 板子题 Sol

    RT Cyber_Tree 出了一道板子题... 这题乍看之下貌似还不戳,但如果您做过类似的题,那么这就是一道板子题.... 首先明确要求的是什么,如果我们只考虑权值最大而不考虑最小距离,那么要求的显 ...

  3. Python 高级特性(3)- 列表生成式

    range() 函数 日常工作中,range() 应该非常熟悉了,它可以生成一个迭代对象,然后可以使用 list() 将它转成一个 list # 判断是不是迭代对象 print(isinstance( ...

  4. uni-app 登录Abp VNexe并获取Token

    uni.request方式登录abp关键代码如下,因abp获取token需要用formdata方式请求所以需要加上请求头 const baseUrl = 'http://127.0.0.1:44323 ...

  5. 配置IIS Express 允许外部访问

    修改applicationhost.config 配置允许外部访问 操作步骤: 1. 查看本机IP地址记录IP地址,例如:10.1.20.138 2. 如下图,找到要发布的站点的名称 记录站点的名称, ...

  6. CLR无法从COM 上下文*****转换为COM上下文*****,这种状态已持续60秒。

    异常信息:CLR无法从COM 上下文0x645e18 转换为COM上下文0x645f88,这种状态已持续60秒.拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的 ...

  7. css 参考手册 部署到本地

    * 到css参考手册网站 http://css.doyoe.com/ 下载chm手册 * 到github下载对应的html页面 cd /Applications/XAMPP/htdocs git cl ...

  8. Python中“if __name__=='__main__':”

    在Python当中,如果代码写得规范一些,通常会写上一句"if name=='main:"作为程序的入口,但似乎没有这么一句代码,程序也能正常运行.这句代码多余吗?原理又在哪里? ...

  9. django ORM教程(转载)

    Django中ORM介绍和字段及字段参数   Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简 ...

  10. GDOI 2021 退役记

    Day -n 时常想自己不学OI会怎样,经常畏惧自己其实没有心里想的那样有能力,去机房来麻痹自己 从 3.21 始加大频率刷题,复习以前都学会,而现在都被抛在脑后的算法 反正都要退役了,成绩也得鲜亮点 ...