Android 6.0 超级简单的权限申请2 (Permission)
写在前面
上次写了一个权限申请的例子Android 6.0 超级简单的权限申请 (Permission),原理是封装权限申请的代码到一个Helper类,然后重写onRequestPermissionsResult方法处理。这已经是很简洁的权限申请方法了,但是还不够,因为这里还需要重写onRequestPermissionsResult方法。所以研究了一番,再写了一个例子,不需要重写onRequestPermissionsResult方法,真正做到一句代码搞定权限申请。
实现原理
封装权限申请的相关代码到一个Helper类中,在申请权限的时候,启动一个Fragment,但不显示,在Fragment中申请权限,也在Fragment中处理权限,最后回调给Helper。
实现过程
- 封装
PermissionHelper类,定义对外开放的方法
/**
* @param permissions e.g. {@link Manifest.permission#CAMERA}
* @return true if all granted, false otherwise.
*/
public static boolean isGranted(Activity activity, String... permissions)
/**
* @param grantedListener run on all permission granted
* @param deniedListener run if one permission denied
*/
public static void requestPermissions(Activity activity,
OnPermissionGrantedListener grantedListener,
OnPermissionDeniedListener deniedListener,
String... permissions)
- 获取
AndroidManifest中注册的权限
private static List<String> getRegisteredInManifestPermissions(Activity activity) {
List<String> list = new ArrayList<>();
try {
PackageInfo packageInfo = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] permissions = packageInfo.requestedPermissions;
if (permissions != null) {
list.addAll(Arrays.asList(permissions));
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return list;
}
- 检查权限是否已经注册
for (String permission : permissions) {
if (!mRegisteredInManifestPermissions.contains(permission)) {
throw new IllegalArgumentException("the permission \"" + permission + "\" is not registered in AndroidManifest.xml");
}
}
- 检查权限是否已经允许,AndroidM以下的设备直接判断为允许
public static boolean isGranted(Activity activity, String... permissions) {
checkPermissions(activity, permissions);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (String permission : permissions) {
if (activity.checkSelfPermission(permission) == PackageManager.PERMISSION_DENIED) {
return false;
}
}
}
return true;
}
- 初始化
Fragment并添加到Activity中
这里的PermissionHelper直接继承Fragment了,直接重写onRequestPermissionsResult处理回调。new Fragment之前先检查此Activity中是否已经存在一个,如果有则直接使用。
Fragment fragment = activity.getFragmentManager().findFragmentByTag(TAG);
if (fragment == null) {
fragment = new PermissionHelper();
FragmentManager fragmentManager = activity.getFragmentManager();
fragmentManager.beginTransaction().add(fragment, TAG).commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
}
- 利用Fragment申请权限
fragment.requestPermissions(permissions, mRequestCode++);
- 处理
onRequestPermissionsResult方法,并把结果正确的回调给用户
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (mOnGrantedListeners.containsKey(requestCode)) {
// 这里规定全部权限都通过才算通过
boolean granted = true;
// 在Activity A申请权限,然后马上跳转到Activity B,则grantResults.length=0
if (grantResults.length == 0) granted = false;
for (int result : grantResults) {
if (result == PackageManager.PERMISSION_DENIED) {
granted = false;
}
}
if (granted) {
OnPermissionGrantedListener listener = mOnGrantedListeners.get(requestCode);
if (listener != null) listener.onGranted();
} else {
OnPermissionDeniedListener listener = mOnDeniedListeners.get(requestCode);
if (listener != null) listener.onDenied();
}
mOnGrantedListeners.remove(mRequestCode);
mOnDeniedListeners.remove(mRequestCode);
}
}
使用方法
直接在Activity中调用下面代码既可,虽然很多行,但只是一句代码哈哈
PermissionHelper.requestPermissions(this, () -> {
// on granted
Toast.makeText(MainActivity.this, "onGranted", Toast.LENGTH_SHORT).show();
}, () -> {
// on denied
Toast.makeText(MainActivity.this, "onDenied", Toast.LENGTH_SHORT).show();
}, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_EXTERNAL_STORAGE);
文件结构图

演示效果图

运行代码可能出现的问题
compileSdkVersion 27,可以改成你电脑中存在的SDK版本。
这里用的是 gradle-4.4-all.zip,如果你用的是其它版本,那么可能会下载超级慢,建议改成你电脑中存在的gradle版本,改文件PermissionHelper/gradle/wrapper/gradle-wrapper.properties即可。
其它问题可以直接联系我。
Android 6.0 超级简单的权限申请2 (Permission)
注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权
Android 6.0 超级简单的权限申请2 (Permission)的更多相关文章
- Android 6.0 超级简单的权限申请 (Permission)
代码地址如下:http://www.demodashi.com/demo/13369.html 背景描述 随着Android系统的不断升级,谷歌对用户的隐私是越来越注重了,给我们开发者带来了更多的繁琐 ...
- Android 6.0 最简单的权限获取方法 RxPermition EasyPermition
Android 6.0 要单独的获取权限 这里提供两种很简单的方法 EasyPermition RxPermition EasyPermition https://github.com/googles ...
- 【Unity游戏开发】Android6.0以上的动态权限申请问题
一.引子 最近公司的游戏在做安全性测试,期间也暴露出了不少安全上的问题.虽然我们今天要说的权限申请和安全性相关不大,但是也会影响到游戏的使用体验等,所以本篇博客中马三就想和大家谈谈Android6.0 ...
- Android 开发基础入门篇: 动态权限申请
说明: 咱们在安装APP的时候经常会看到,类似于下面的提示 goolge为了保护用户隐私,在android 6.0开始,某些隐私权限,必须用户允许以后,内部程序方可使用 这就涉及到权限动态申请问题. ...
- Android 6.0以上 需要运行时申请的权限
转载:http://www.cnblogs.com/tangs/articles/6377347.html 自从Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifes ...
- Android 6.0的运行时权限
原文 http://droidyue.com/blog/2016/01/17/understanding-marshmallow-runtime-permission/ 主题 安卓开发 Andr ...
- 聊一聊 Android 6.0 的运行时权限
权限一刀切 棉花糖运行时权限 权限的分组 正常权限 正常权限列表 特殊权限危险权限 请求SYSTEM_ALERT_WINDOW 请求WRITE_SETTINGS 必须要支持运行时权限么 不支持运行时权 ...
- 聊一聊Android 6.0的运行时权限
Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...
- android 6.0之后动态获取权限
Android 6.0 动态权限申请 1. 概述 Android 6.0 (API 23) 之前应用的权限在安装时全部授予,运行时应用不再需要询问用户.在 Android 6.0 或更高版本对权限 ...
随机推荐
- hdu 6047 Maximum Sequence 贪心
Description Steph is extremely obsessed with “sequence problems” that are usually seen on magazines: ...
- HDU 6035 Colorful Tree (树形DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 我们计算 ...
- [xsy2880]取石子游戏
题意:有$n$堆石子,每堆石子数量相同,以质因数分解给出,不停地从$1$到$n$依次拿石子,使得取完后石子个数为原来的因数(不能不取),当一堆只剩$1$个时结束,问在每堆石子结束的方案数 记石子个数为 ...
- linux centos下安装docker
1.在vm中装好好centos后,更新内核 运行docker需要内核版本为3.8或者更高的版本,内核必须支持一种合适的存储驱动(Drivice Mapper.AUFS.vfs.btrfs.ZFS),默 ...
- Java学习笔记(16)
需求:使用LinkedList存储一副扑克牌,然后实现洗牌功能 package cn.itcast.list; import java.util.LinkedList; import java.uti ...
- TZOJ 数据结构实验--循环队列
描述 创建一个循环队列,队列元素个数为4.能够实现队列的初始化.入队列.出队列.求队列长度等操作. 循环队列数据类型定义如下: typedef struct{ int data[Max]; in ...
- 条件注释判断浏览器<!--[if !IE]>
<!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]--><!--[if IE]> 所有的IE可识别 <![e ...
- 【OpenJudge9277】【递推】Logs Stacking堆木头
Logs Stacking堆木头 总时间限制: 1000ms 内存限制: 131072kB [描述] Daxinganling produces a lot of timber. Before loa ...
- Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树
D. Zip-line 题目连接: http://www.codeforces.com/contest/650/problem/D Description Vasya has decided to b ...
- Codeforces Round #344 (Div. 2) A. Interview 水题
A. Interview 题目连接: http://www.codeforces.com/contest/631/problem/A Description Blake is a CEO of a l ...