Android6.0权限申请源码解析及其注意事项
来源:互联网 发布:头号共谍常凯申 知乎 编辑:程序博客网 时间:2024/05/21 09:09
一、概述
随着android版本的不断升级,现在开发App肯定都是需要适配6.0及其以上的版本了,Google对手机安全的越来越重视,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化。关于权限机制的变化网上的内容很多参考android6.0运行权限处理本篇文章主要根据源码来分析申请权限时一些注意的事项。
二、权限申请流程
1、Activity.checkSelfPermission(String permission)
2、Activity.requestPermissions(@NonNull String[] permissions, int requestCode)
3、Activity.shouldShowRequestPermissionRationale(@NonNull String permission)
4、Activity.onRequestPermissionsResult(int requestCode, @NonNull String[] permissions@NonNull int[] grantResults)
第一个方法是解析你当前需要申请的权限是否是被通过的,如果是允许的就返回 PERMISSION_GRANTED
,第二个方法是请求权限,第三个方法是判断当前的权限状态是否是已经被拒过一次了,它在你第一次拒绝请求权限之后和永远拒绝权限之前这段时间内全部返回true,所以当用户第一次拒绝权限之后再次请求时给用户提示为什么app需要这个权限、打消用户的顾虑。第四个方法就不多说了,返回的是请求的结果。
本文主要分析的是requestPermissions这个 函数及其一些注意事项!
*/ public final void requestPermissions(@NonNull String[] permissions, int requestCode) { if (mHasCurrentPermissionsRequest) { Log.w(TAG, "Can reqeust only one set of permissions at a time"); // Dispatch the callback with empty arrays which means a cancellation. onRequestPermissionsResult(requestCode, new String[0], new int[0]); return; } Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions); startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null); mHasCurrentPermissionsRequest = true; }
这是android7.0的源码里面的。mHasCurrentPermissionsRequest这个是一个布尔值的flag,标记当前是否有正在请求的权限。因为方法是异步执行的,所以如果你在申请权限的时候连续两次执行此方法,你会在方法第二次请求的时候他会直接执行onRequestPermissionsResult方法,返回的 permissions和grantResults都是长度为0的空数组,这是如果你在onRequestPermissionsResult不判断长度直接取值会奔溃报数组越位,所以大家在返回结果处理的时候最好做一下长度不为0的判断,最好不要在上次请求结果没有返回的时候就再次执行新的权限请求,因为这样是没有意义的!
private void dispatchRequestPermissionsResult(int requestCode, Intent data) { mHasCurrentPermissionsRequest = false; // If the package installer crashed we may have not data - best effort. String[] permissions = (data != null) ? data.getStringArrayExtra( PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0]; final int[] grantResults = (data != null) ? data.getIntArrayExtra( PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0]; onRequestPermissionsResult(requestCode, permissions, grantResults); }
dispatchRequestPermissionsResult方法分发处理的结果,这时mHasCurrentPermissionsRequest重新置为false,表示当前没有正在请求的权限!所以为了防止同时多次调用requestPermissions方法可以添加一个布尔值作判断,实现代码如下
private isRequesting=false; //做请求的统一入口 private void requestMyPermission(String[] permissions, int requestCode) { if (!isRequesting) { isRequesting = true; ActivityCompat.requestPermissions(this, permissions, requestCode); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(isRequesting&&permissions.length!=0){ isRequesting=false; //do you want } }
这样就能避免连续多次请求导致无效请求和处理出错的情况!
还有一点的是对于Fragment内的权限请求,最好用v4包中的Fragment,因为android.app.Fragment内的requestPermissions方法
Added in API level 23
void requestPermissions (String[] permissions, int requestCode),需要api23及其之上才能使用的。而v4包中的requestPermissions方法没有版本要求,end~
- Android6.0权限申请源码解析及其注意事项
- Android6.0权限申请
- Android6.0权限申请
- android6.0权限申请
- Android6.0权限申请
- Android6.0权限申请
- Android6.0权限申请
- Android6.0权限申请
- Android6.0+权限申请
- Android6.0动态申请权限(高德地图源码)
- Android6.0权限申请模型
- Android6.0 权限申请封装
- android6.0 动态申请权限
- Android6.0重要权限申请
- Android6.0以上权限申请
- Android6.0权限申请解决方案
- Android6.0动态权限申请
- Android6.0:动态权限申请
- 获取数据的方式
- 原生js利用鼠标滚轮实现滚动到当前页面实现动画效果
- c语言实现猜数字游戏
- 【第14周 项目3 - 二叉树排序】
- 11月英语总结
- Android6.0权限申请源码解析及其注意事项
- 1.事件委托的原理以及优缺点 2. 手写原生js实现事件代理,并要求兼容浏览器
- SQL Server BCP命令参数详解
- 简单的ListView
- 冒泡排序
- failed to resolve:com.android.support:appcompat
- maven安装
- 1622-5 孔富晨 总结《2016年12月4日》 【连续第65天总结】
- C++复习之前言