Android---动态权限适配问题

在 Android6.0,即 API 23 之前,App 需要的权限都会在安装阶段向用户展示,而在 App 运行期间不需要动态判断权限是否已申请。从 6.0 之后的版本开始,Android 系统做了一次大的改动。对于部分权限,App 需要在代码中动态申请相应的权限。

权限分类

Android 权限分两种:普通权限和危险权限。在两种权限都需要在 AndroidManifest.xml 清单文件中声明。

普通权限(Normal Permission):在程序运行时期自动获取,只需要在清单文件中声明。常用的是 INTERNET 网络权限。

危险权限(Dangerous Permission):App 中可能存在一些操作会查看与用户隐私相关的信息,比如查看用户的通讯录或者图库等。对于这一类操作,Android 系统要求 App 主动向用户展示操作所需要的权限。只有用户授权之后,才可以进行下一步操作。

权限动态申请流程

一次完整的权限申请流程,如下图所示

对上图申请流程做一个简单说明

首先,判断 API 版本是否小于 23。如果版本低于23,则不需要动态申请权限,否则调用 checkSelfPermission() 方法检查权限是否已申请。如果,checkSelfPermission 返回 false,说明权限并没有申请,此时需要调用 requestPermission() 方法,主动发送申请权限的操作。

shouldShowRequestPermissionRationale

在调用 requestPermission 方法申请权限之前,需要判断是否需要展示 shouldShowRequestPermissionRationale,该方法会返回以下两种情况:

1)返回 true。用户之前在申请权限操作时,点击了“拒绝”按钮,但是没有选择“Never ask again”选项。

2)返回 false。有两种情况会返回 false

a. 用户从来没有申请过次权限;

b. 用户之前选中拒绝,并且勾选了 “Never ask again”选项。

处理办法

针对返回 true 的情况,很容易处理。这种情况表示用户已经拒绝申请操作,但是并没有选中 “Never ask again” 选项。因此,我们只需要再次调用 requestPermission 方法申请权限即可。系统会自动弹出申请权限的对话框。

对于放回 false 的情况稍微麻烦一点,因为有两种情况会返回 false。针对着两种情况所对应的返回操作也不一样。

如果用户从来没有申请过次权限,那么就同上面返回 true 的情况一样,直接调用 requestPermission() 方法申请权限即可。如果是因为用户之前拒绝申请操作并且勾选了 “Never ask again” 选项,此时我们不应该再执行 requestPermission 方法。通过弹出自定义的对话框,提示用户此操作必须通过权限申请之后才可以继续进行,并给用户提供进入权限设置界面的入口。

注意:shouldShowRequestPermissionRationale 返回 true 的情况,在很多国内厂商的手机中设置了自动屏蔽,也就是没有返回 true 的情况,比如华为、小米手机。

代码演示

接下来以申请通讯录权限为例,来演示如何进行动态权限适配。

首先,判断系统版本是否高于23,代码如下

只有在API版本高于23的系统中,才需要动态申请权限。

在申请之前,还需要检查当前 App 是否已经获取到相应的权限,避免重复申请。如下所示

上图中的 PackageManager.PERMISSION_GRANTED 表示权限已经获取。接下来就是申请权限的流程

上文中已经介绍,在申请权限之前需要调用 shouldShowRequestPermissionRationale 判断用户之前的操作。因此代码修改如下

图中1处,shouldShowRequestPermissionRationale 返回 true,直接调用 requestPermissions 再次申请权限即可。但是,对于返回 false 的情况需要特殊处理,因为有两种情况返回 false。

可以借助于 SharedPreference 判断是否为用户第一次申请权限操作。代码如下所示

上图中使用 SharedPreference 来保存用户是否第一次申请权限的状态值,默认情况为 true。当执行一次权限申请后,调用 firstTimeAsking() 方法将其设置为 false。

权限申请操作封装

App 中会有很多调用危险权限的方法,如果每一次执行这些代码都复制粘贴上述这些权限申请的代码,会显得代码很冗余。因此,可以将动态权限申请的操作封装到工程中的某个 Util 类中,并提供给调用者相应的回调接口。部分核心代码如下

最后,只需要在 BaseActivity 中调用此方法时,传入具体实现的 PermissionRequestListener 即可。如下所示

第三方库使用

对于 Permission 的动态申请,也可以借助于开源的第三方库来加快开发速度。目前,对于 Permission 动态权限申请比较好的开源库有:a)Dexter;b)easypermissions;c)PermissionsDispatcher。

但是,第三方库的使用也具有一定的隐患。不同版本中 Android 系统对 Permission 的处理政策并不完全一致,在新版本的系统中很有可能会添加对权限申请更严格的请求策略。

比如,在 Android 10 中,增加了对外置存储访问的限制。正常情况下,我么可以通过以下代码获取外置存储的根路径,然后在此目录下创建 App 相应的文件缓存数据。

但是,从 Android 10(API 29)开始,App 层没有访问此路径的权限。无论在 AndroidManifest 文件中加上对应的权限,还是使用 ActivityCompact.requestPermissions 动态申请权限,都无法实现访问。目前官方提供的临时解决方案是在 AndroidManifest.xml 清单文件中添加如下设置

但是,如果我么使用的是第三方库处理动态权限申请操作,如果第三方库没有做版本适配,或者做了相应的适配修改,但是并没有升级第三方库的版本。都会造成在 Android 10 设备上处理文件发生异常

总结

本次主要介绍了 Android 系统中申请权限相关的知识点,主要是针对 Android 版本 23 之后的动态申请做了详细介绍。需要掌握的方法:1)checkSelfPermission 检查某权限是否已经申请;2)requestPermissions 主动发送申请权限的请求;3)shouldShowRequestPermissionRationale 判断用户之前对申请权限做出的相应动作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/175253.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在线预览编辑PDF::RAD PDF for ASP.NET

RAD PDF for ASP.NET作为功​​能最齐全的基于 HTML 的 PDF 查看器、编辑器和 ASP.NET 表单填充器,RAD PDF 为传统 PDF 解决方案提供了灵活而强大的替代方案。与 Adob​​e Acrobat Reader 不同,RAD PDF 几乎可以在任何现代网络浏览器中运行,…

云原生实战课大纲

1. 云原生是什么 原生应用(java,pyrhon) 上云的过程应用上云遇到的问题1.微服务的拆分 微服务的访问关系应用的架构云原生适合什么样的人去学具备什么样的前提条件云原生要学习什么docker k8s devlops server mesh jks k8s监控吧自己的微服务部署上…

Python - GFPGAN + MoviePy 提高人物视频画质

目录 一.引言 二.gif_to_png 三.gfp_gan 四.png_to_gif 五.总结 一.引言 前面我们介绍了 GFP-GAN 提高人脸质量 与 OCR 提取视频台词、字幕,前者可以提高图像质量,后者可以从视频中抽帧,于是博主便想到了将二者进行结合并优化人物 GIF …

软件工程-第7章 面向对象方法基础

第7章 面向对象方法基础 面向对象的基本概念 面向对象方法的世界观:一切系统都是由对象构成的,他们的相互作用、相互影响,构成了大千世界的各式各样系统。面向对象方法是一种以对象、对象关系等来构造软件系统模型的系统化方法。 面向对象 …

界面控件DevExpress WPF Splash Screen,让应用启动画面更酷炫!

DevExpress WPF的Splash Screen组件可以为应用程序创建十分酷炫的启动屏幕,提高用户在漫长的启动操作期间的体验! P.S:DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress …

负载均衡原理

负载均衡原理是什么? 负载均衡Load Balance)是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。负载均衡,其核心就是网络流量分发,分很多维度。 …

Java 通过POI快速导入带图片的excel并且图片不会丢失

## 通过POI快速导入带图片的excel并且图片不会丢失导入带图片的excel,这里也是研究了很久,在之前的博客中也有说明过,在项目使用过程中,发现很多时候导入响应很慢,而且每次导入图片都会丢失几张,所以又花了点时间研究修改了下,具体如下: 这边在导入时,通过自定义注解…

【3dMax室内照明】如何在V-ray中设置照明分析?

如何在V-ray中设置照明分析? 在3dMax的V-Ray Next中添加了新的“照明分析”工具,以帮助您测量和分析场景中的灯光级别。您将能够创建假彩色热图和数据覆盖,以显示亮度(以坎德拉为单位)或照度(以勒克斯为单位…

性能测试 —— Jmeter分布式测试的注意事项和常见问题

Jmeter是一款开源的性能测试工具,使用Jmeter进行分布式测试时,也需要注意一些细节和问题,否则可能会影响测试结果的准确性和可靠性。 Jmeter分布式测试时需要特别注意的几个方面 1. 参数化文件的位置和内容 如果使用csv文件进行参数化&…

vscode+python开发之虚拟环境和解释器切换

需求情景: 现在我们要开发多个项目比如:项目A,项目B、项目C,他们每个项目需要依赖不同的库。每个项目依赖的解释器也不一样怎么办? 项目A:需要在python3.7环境运行 依赖aadd3.2库 项目B、需要在python3.11…

Xshell+Xftp通过代理的方式访问局域网内网服务器

最近在部署项目时遇到只有1台服务器拥有公网ip,其它服务器只有局域网ip,当然其它服务器可以正常访问网络,例如如下模型。之前访问其它几台服务器,都是先通过登录公网IP服务器,然后在Xshell里面执行ssh远程连接&#xf…

Vatee万腾的数字化掌舵:Vatee科技引领未来的新高度

随着数字化时代的到来,Vatee万腾以其卓越的科技决策力成为引领潮流的掌舵者。 Vatee万腾通过对科技前沿的不懈探索,站在了数字化创新的最前沿。其领先的科技团队致力于发掘并应用最新的数字技术,为用户提供卓越的数字化体验。 Vatee万腾以其…