博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android M 封装过的运行时权限处理
阅读量:6760 次
发布时间:2019-06-26

本文共 4665 字,大约阅读时间需要 15 分钟。

本文对Android M的运行时权限进行了代码封装,有助于项目开发业务代码中大面积的出现重复的运行时权限处理代码

1 前言

Android M 运行时权限想必大家已经不陌生了。在这还是放出一篇经典的对于运行时权限的说明和解释的说明。

同时Google也提供了帮助处理的第三方库EasyPermission,可以见这篇文章。

这个项目从Easypermissions中fork出来,翻译了中文文档,并封装了权限处理代码,使可以简化每次申请权限的流程。

2 出现的问题

所有的封装和处理都是由开发中出现的各种问题而推动的。很明显,权限处理的代码缺点就是你不能处理一次就行了。由于用户可以在系统设置-应用设置里手动设置权限,如下图。

权限修改

所以需要在每次遇到Dangerous Permission 相关的业务处理时都要添加权限判断处理。虽然代码不多,但是需要同时在onRequestPermissionsResult、onPermissionsGranted、onPermissionsDenied等多处进行代码处理。就会显得很乱,降低代码的可读性。

最理想的方式当然时只要在需要的地方加一行代码即可以处理权限。封装权限处理应运而生。

3 封装后的处理

我们先直接看封装后的权限处理代码变成了什么样。下面是一个打开摄像头的业务,调用业务前需要处理摄像头权限。

public void cameraTask() {    String[] perms = {Manifest.permission.CAMERA};    performCodeWithPermission(getString(R.string.rationale_camera), RC_CAMERA_PERM, perms, new PermissionCallback() {        @Override        public void hasPermission(List
allPerms) { Toast.makeText(SimplePermActivity.this, "TODO: Camera things", Toast.LENGTH_LONG).show(); } @Override public void noPermission(List
deniedPerms, List
grantedPerms, Boolean hasPermanentlyDenied) { if (hasPermanentlyDenied) { alertAppSetPermission(getString(R.string.rationale_ask_again), RC_SETTINGS_SCREEN); } } });}@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SETTINGS_SCREEN) { // Do something after user returned from app settings screen, like showing a Toast. Toast.makeText(this, R.string.returned_from_app_settings_to_activity, Toast.LENGTH_SHORT) .show(); }}复制代码

注意下上面代码的alertAppSetPermission方法作用是,当权限被拒绝时,判断如果点了不再询问被拒绝的情况后弹出一个alert框,提示用户前往系统设置开启权限,这样更加人性化,不然如果用户拒绝过一次后之后的该权限将全部都会被拒绝。如下图

系统提示框

再看下alertAppSetPermission方法有2个重载方法,有一个比另一个多了个requestCode参数。目的是当用户跳转系统设置返回后,有的需求可能希望返回后自动再判断用户有没有在系统设置中修改过权限从而直接继续下一步操作。这样实现onActivityResult方法,在系统页面返回时再次判断权限是否授予。

通过上面代码可以发现,封装过后只需要在需要权限处理的地方加一个performCodeWithPermission,然后再重载onActivityResult方法。如果没有页面返回后自动继续下一步的需求的话那就只需要调用performCodeWithPermission就可以了。做到了“伪一行代码”处理运行时权限。哈哈!

没有对比就没有伤害,我再把没有封装过的完整权限处理代码贴上来对比下。(使用了EasyPermission)

@AfterPermissionGranted(RC_CAMERA_PERM)public void cameraTask() {    if (EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA)) {        // Have permission, do the thing!        Toast.makeText(this, "TODO: Camera things", Toast.LENGTH_LONG).show();    } else {        // Ask for one permission        EasyPermissions.requestPermissions(this, getString(R.string.rationale_camera),                RC_CAMERA_PERM, Manifest.permission.CAMERA);    }}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {    super.onRequestPermissionsResult(requestCode, permissions, grantResults);    // EasyPermissions handles the request result.    EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);}@Overridepublic void onPermissionsGranted(int requestCode, List
perms) { Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size());}@Overridepublic void onPermissionsDenied(int requestCode, List
perms) { Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size()); // (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN." // This will display a dialog directing them to enable the permission in app settings. if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { new AppSettingsDialog.Builder(this, getString(R.string.rationale_ask_again)) .setTitle(getString(R.string.title_settings_dialog)) .setPositiveButton(getString(R.string.setting)) .setNegativeButton(getString(R.string.cancel), null /* click listener */) .setRequestCode(RC_SETTINGS_SCREEN) .build() .show(); }}@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SETTINGS_SCREEN) { // Do something after user returned from app settings screen, like showing a Toast. Toast.makeText(this, R.string.returned_from_app_settings_to_activity, Toast.LENGTH_SHORT) .show(); }}复制代码

发现比封装过的多了onRequestPermissionsResult、onPermissionsGranted、onPermissionsDenied三个回调的处理。就是说每次写权限处理需要写4~5个地方。而封装过的只需要写1~2个即可。

4 总结

所有的代码被封装在了BaseActivity中。其实很简单,不作过多解释了。大家可以到Github上自行参考。

所有的代码见Github:

在项目开发中,多处需要进行权限处理,必要的封装可以大大增加代码可读性,专注于业务代码的编写。

更多文章关注我的公众号

我的公众号

转载地址:http://cxbeo.baihongyu.com/

你可能感兴趣的文章
关于vue父子组件之间事件触发及数据传递问题
查看>>
GraphQL:了解Spring Data JPA / SpringBoot
查看>>
每隔1s打印0-5
查看>>
在安卓手机中rem单位border-radius:50%画圆变形的解决方案
查看>>
前端在h5页面调起微信支付接口和支付宝接口(日常笔记)
查看>>
Bundler 2.0 发布
查看>>
自动化部署工具Syncd v1.1.0发布,提供二进制安装包
查看>>
一位老码农的分享:一线程序员该如何面对「中年危机」?
查看>>
关于ES6深度拷贝
查看>>
财会小白的办公室自救指南
查看>>
Java核心技术笔记 接口、lambda表达式与内部类
查看>>
Docker 验证 Centos7.2 离线安装 Docker 环境
查看>>
【译】你可能不需要派生状态
查看>>
自动化瓦力多渠道打包python脚本
查看>>
各类型的 toString 方法合集
查看>>
Python爬虫 --- 2.4 Scrapy之天气预报爬虫实践
查看>>
GAN是一种特殊的损失函数?
查看>>
数据告诉我们:什么样的程序员最抢手!
查看>>
javascript 正则表达式 (一)
查看>>
mac虚拟环境下linux系统搭建及系统初始化记录——使用VMWare及RHEL 7
查看>>