6.0运行时权限的总结与实践

掌握Android 6.0运行时权限管理与实践 由于旧版Android系统权限请求对话框不可自定义,开发者必须确保应用逻辑能够在无自定义UI的情况下也能正常工作。通过合理设计用户引导流程,确保用户体验不被破坏。 阅读详情

运行时权限.png

为什么需要6.0运行时权限
  • 更友好

6.0以前的安装时权限,会在应用安装时列出所有需要的权限,当列出一些危险权限时,用户不知每个权限的具体用途,可能因为这些权限警告而放弃安装应用。对于一些非装不可的应用,用户则不得不被迫接受所有权限,很容易安装了一些流氓APP,体验不佳。
6.0以后的运行时权限,可以在调用相关功能之前判断权限授权状态,并自定义提示弹框告知用户权限用途,使用户清楚了解之后,再授权使用。

5.0和6.0的安装页面.png

  • 更稳定

6.0系统的手机对于每个应用,都有个权限设置页面,可以手动开关权限,如果用户在设置页面误关了某个权限,若没在程序运行时做判断,则会导致相关功能的调用失败,引起崩溃等。

5.0和6.0的权限设置页面.png

如何实现运行时权限
  • 设置targetSdkVersion

只有targetSdkVersion>=23,且安装在6.0以上的手机时,运行时权限机制才能正常运作

手机系统targetSdkVersion<23targetSdkVersion>=23
5.0+安装时权限安装时权限
6.0+安装时权限运行时权限

* 代码实现

在需要使用某项权限时,通过V4包的checkSelfPermission判断权限是否授权,通过requestPermissions申请某项权限

// 需要执行某项需要权限的操作时
if (ContextCompat.checkSelfPermission(this, "某项权限") == PackageManager.PERMISSION_GRANTED) {
   // 执行操作
} else {
   // 请求权限
   ActivityCompat.requestPermissions(this, new String[]{"某项权限"}, requestCode);
}

在Activity的onRequestPermissionsResult回调方法中,处理权限授权结果

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
   if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
       // 授权成功,执行操作
   } else {
       // 权限被拒绝
       if (ActivityCompat.shouldShowRequestPermissionRationale(this, "权限名称")) {
           // shouldShowRequestPermissionRationale=true: 表示权限被拒绝,且没有勾选"never ask again"
           // 正常的权限被拒绝流程,可以继续申请权限,重复以上流程
       } else {
           // shouldShowRequestPermissionRationale=false: 在权限被拒绝,且勾选"never ask again"的情况下,返回false
           // 继续申请权限的时候,不会再弹出默认的系统弹框,需要自定义提示弹框,并引导用户去权限设置页面,手动开启权限
       }
   }
}
LsPermission工具类的使用
  • 主要实现逻辑参考PermissionGen,封装了权限判断,请求,结果处理等通用逻辑,目前只支持context=AppCompatActivity,如果在Fragment中使用时可以调用getActivity()获取上层AppCompatActivity。

demo演示.gif

private void normal() {
   final String[] permissions =
       new String[] {Manifest.permission.CALL_PHONE, Manifest.permission.ACCESS_FINE_LOCATION};

   PermissionUtil.request(this, permissions, new OnPermissionAdapter() {
       /**
        * @desc 申请的权限全被授权
        */
       @Override
       public void onGrant() {
           showToast("权限被同意");
           callPhone();
       }

       /**
        * @desc 权限被拒绝
        */
       @Override
       public void onDeny(List<String> permissions) {
           showToast("用户拒绝授权" + permissions.toString());
       }

       /**
        * @desc 权限被拒绝,且勾选"never ask again"
        */
       @Override
       public void onNeverAsk(List<String> permissions) {
           showToast("用户拒绝授权, 并勾选 never ask again " + permissions.toString());
           PermissionUtil.showNeverAskDialog(MainActivity.this, "这个权限很重要");
       }

       /**
        * @desc 无论权限授权成功还是失败,都会回调
        */
       @Override
       public void always(List<String> grantPermissions, List<String> denyPermissions,
           List<String> foreverDenyPermissions) {
           showToast("授权: " + grantPermissions.toString() + "\n 拒绝: " + denyPermissions.toString()
               + "\n never ask: " + foreverDenyPermissions.toString());
       }
   });
}

/**
* @desc 将权限回调转发给PermissionUtil处理
* @author listen
* @date 2017/2/24 13:47
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
   PermissionUtil.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
   super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
  • PermissionUtil内部通过SparseArray保存了requestCode和权限回调的键值对,避免了连续点击时重复回调情况,对于不同的权限申请,推荐使用不同的requestCode,避免回调覆盖的问题。
private static SparseArray<OnPermissionListener> mPermissionRequestList = new SparseArray<>();

public static void request(final Context context, int requestCode, String[] permissions,
                          OnPermissionListener listener) {
   /** 存在未授权的权限 */
   synchronized (mPermissionRequestList) {
       if (null != mPermissionRequestList.get(requestCode)) {
           /** 当前权限请求已经存在,不重复添加 */
           log("the same permission is requesting");
       } else {
           /** 将当前权限请求加入队列 */
           /** 如果一个页面中存在分别触发A, B多个权限的情况, 则最好将不同权限申请对应不同的requestCode, 存入SparseArray分别处理 */
           mPermissionRequestList.put(requestCode, listener);

           /** 执行权限申请 */
           ActivityCompat.requestPermissions();
       }
   }
}

在权限回调的时候从SparseArray移除Listener

public static void onRequestPermissionsResult(Context context, int requestCode, String[] permissions,
                                                  int[] grantResults) {
   final OnPermissionListener listener;
   synchronized (mPermissionRequestList) {
       listener = mPermissionRequestList.get(requestCode);
       mPermissionRequestList.remove(requestCode);
   }

   if (null != listener) {
       /** 执行回调 */
       listener.onGrant();
       listener.onDeny();
       listener.onNeverAsk();
       listener.always();
   } else {
       log("request is not exists");
   }
}

代码地址:LsPermission

除了基本的权限申请逻辑的封装以外,还写了类似微信,支付宝,百度地图等在启动页的权限申请Demo,算是PermissionUtil的简单运用。

参考:
Android 6.0 运行时权限处理完全解析
Android 6.0 运行时权限管理最佳实践
聊一聊Android 6.0的运行时权限

官方:
在运行时请求权限
权限最佳做法

python数据处理与分析案例,python如何进行数据处理 大家好,本文将围绕基于python的数据处理案例展开说明,python数据处理与分析案例是一个很多人都想弄明白的事情,想搞清楚python如何进行数据处理需要先了解以下几个事情。大家好,小编来为大家解答以下问题,python数据处理案例步骤及其代码,python数据处理与分析教程,今天让我们一起来看看吧!哈喽~今天学习记录的是数据分析实训小案例。就用这个案例来好好巩固一下 python 数据分析三剑客。 阅读详情

相关推荐

超详细neo4j安装教程

一、neo4j简介 最近开始学习知识图谱,所以首先想先学习一下neo4j的使用。 Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。由于知识图谱中存在大量的关系型信息(实体—关系—实体), 使用结构化数据库进行存储将产生大量的冗余存储信息, 因此将图数据库作为知识图谱的存储容器成为流行的选择。当前较为常用的图数据库主要有 Neo4j 等。 二、neo4j的安装 功能快捷键 撤销:Ctrl/Command + Z 重做:Ctrl/Command + Y 加粗:Ctrl/Co

qq_38335648的博客 9万+

webview打开的网页请求摄像头或文件的处理

重写WebChromeClient 的 onPermissionRequest()方法和onJsAlert()方法。

qq_15596445的博客 1057

Python+Appium实现泛微OA自动打卡:5分钟搭建移动端自动化脚本

移动端自动化测试是软件测试与办公自动化领域的重要技术方向,其核心原理是通过程序模拟用户对手机应用界面的操作,实现重复性任务的自动执行。Appium作为主流的开源移动端自动化框架,基于WebDriver协议,支持跨平台且无需修改被测应用,为自动化脚本开发提供了标准化接口。在工程实践中,结合Python简洁的语法和丰富的生态,可以快速构建稳定可靠的自动化解决方案。这一技术组合的价值在于能够高效处理“重复性、低价值、高频率”的日常操作,例如考勤打卡、数据填报等办公场景,显著提升工作效率。本文以泛微OA Emobi

weixin_28836875的博客 391

Android之 市场上架和疑难问题总结

开发经验总结

qq_29848853的博客 1741

【OWL部署】Manus又一开源平替OWL真的很好用吗?手把手带你部署并运行你的AI助手OWL(对接Qwen、硅基流动接口)

本文介绍了通用人工智能OWL的部署及国内接口对接,全篇干货满满,手把手教学。

MosuoLc的博客 4046

六维力传感器选型指南:电阻式vs电容式,哪个更适合你的工业场景?

本文深入解析六维力传感器在工业自动化中的选型要点,重点对比电阻式与电容式传感器的核心原理、环境适应性及成本结构。针对不同工业场景(如高精度装配、重载机器人等),提供专业选型建议,帮助工程师优化系统性能与经济效益。

weixin_42525005的博客 396

Android APP WebView 为 H5动态授权 H5获取APP权限

Android APP WebView 为 H5动态授权 H5获取APP权限

Jason_HD的博客 4481

关于mos管的压降问题(项目遇到问题总结)

在研发过程中没有出现问题的板子,到了小批时竟出现雷达一直在触发???找了大几天,没有头绪。心中疑惑颇多,加上老板催促,自考等原因,真是压力山大。4月份自考,只有差不多一个月时间了吧,没有什么大的收获,反而在查找硬件问题的过程中,发现了一个自己忽视的一个问题,就是关于Mos管的压降问题。 备考的过程崎岖不平,工作又问题多多,孰轻孰重,如何取舍?从心理来说,不想取舍什么,只是有所得就可以,过不了就过不了呗,已经毕业十五年了,没这个本科文凭不也过来了吗?只是代表了自己在这一段时间的思考,自己兴趣吧,没什么大不了

guangod的博客 2万+

Android WebView详解(一):相关API介绍

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33971130的博客 385

傻瓜教程:使用GeoServer发布离线地图服务

一、离线地图下载 离线地图分为两种:一种叫“金字塔瓦片”数据,一种叫“矢量地图数据”。我们看的在线地图比如,百度,谷歌,高德等等网页上的地图,都是金字塔瓦片;另外一种是手机上用来导航的,比如高德地图APP,也可以下载离线地图数据,这个就是矢量的。 卫星影像地图都是金字塔瓦片,无矢量数据。 因此,我们所说的离线地图下载通常都是指离线地图金字塔瓦片数据下载。 离线地图金字塔瓦片搭建的离线地图服务分很多种:一般有WEB方式,TMS、WMTS/WMS等等,不同的应用有不同...

米兰的小码农的博客 1万+

【实战指南】RF-DETR多场景部署:从工业质检到自动驾驶的SOTA模型应用

本文深入解析了SOTA目标检测模型RF-DETR在工业质检与自动驾驶等多场景下的实战部署指南。该模型基于Transformer架构,在COCO数据集上实现了实时检测与高精度的突破,并凭借其强大的泛化能力,在RF100-VL等复杂数据集上表现出色。文章提供了从快速Demo、工业缺陷检测微调、车载自适应部署到多硬件平台性能优化的完整解决方案,帮助开发者高效应用这一先进模型。

weixin_29070861的博客 476

Android WebView 开发使用笔记

最近在做的一个项目,涉及到关于WebView的监控,因此花了些时间熟悉对WebView的使用以及注意事项,并通过在页面加载完成后插入JS代码成功监控到了各所需的信息,目前功能已全部完成,因此打算写篇文章记录一下,

jwcqc的博客 1050

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android 6.0 运行时权限管理最佳实践

Android 6.0 运行时权限管理最佳实践 这是一篇迟来的文章,Android M已经发布一年多了(6.0的变化),在Android M中权限系统被重新设计,发生了颠覆性的变化,很多人把握不好这个变化,一是对这个权限策略和套路还没有摸透,二是没有一个很好的实践来支撑,在我的技术开发群里很多人问我关于权限的问题,往往我都没有直接回答,因为这个问题不是一两句说的清楚的,这几点是今天我写这

东方升起代码的博客 634

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Android 6.0 运行时权限管理实践

这是一篇迟来的博客,Android M已经发布一年多了(6.0的变化),在Android M中权限系统被重新设计,发生了颠覆性的变化,很多人把握不好这个变化,一是对这个权限策略和套路还没有摸透,二是没有一个很好的实践来支撑,在我的技术开发群里很多人问我关于权限的问题,往往我都没有直接回答,因为这个问题不是一两句说的清楚的,这几点是今天我写这篇博客的原因。这里有一切关于Android运行时权限你需要...

商务合作|问题讨论|交流学习 请联系作者微信,加微信请务必注明来意,博客主页有联系方式 723

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Android 6.0 运行时权限管理最佳实践 (详解)

转载来自严大,留作学习。这是一篇迟来的博客,Android M已经发布一年多了(6.0的变化),在android M中权限系统被重新设计,发生了颠覆性的变化,很多人把握不好这个变化,一是对这个权限策略和套路还没有摸透,二是没有一个很好的实践来支撑,在我的技术开发群里很多人问我关于权限的问题,往往我都没有直接回答,因为这个问题不是一两句说的清楚的,这几点是今天我写这篇博客的原因。这里有一切关于Andr

say_from_wen的博客 1017

Android6.0运行时权限最佳实践

一. 背景 6.0后Google对Android的权限管理做了大的调整,可以让用户自由的选择是否允许打开一些涉及个人隐私的权限。 二. 新的变化 新的权限机制更好的保护了用户的隐私,Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到

Just_Sanpark的专栏 822
上一篇: Android源码中的一种单例实现
下一篇: 性能优化(一)堆内存分析
listen2code
博客等级 码龄10年 7粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值