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 或更高版本对权限 ...
随机推荐
- EasyUI学习总结(一)——EasyUI入门(转载)
本文转载自:http://www.cnblogs.com/xdp-gacl/p/4075079.html 一.EasyUI下载 EasyUI官方下载地址:http://www.jeasyui.com/ ...
- jvm 哪些是不会被gc回收的
韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com
- 【贪心】【set】zoj3963 Heap Partition
贪心地从前往后扫,每到一个元素,就查看之前的元素中小于等于其的最大的元素是否存在,如果存在,就将它置为其父亲.如果一个结点已经是两个儿子的父亲了,就不能在set中存在了,就将他删除.如果然后将当前元素 ...
- springmvc之文件上传、下载
1.接收到的是图片的流时 //上传头像 @RequestMapping(value = "/uploadHeadSculpture", method = RequestMethod ...
- File I/O知识点
问题1:File类的作用? 解答:File 类用于访问文件或目录的属性.File类位于java.io包中. 问题2:流?及流的分类? 解答:流是指一连串流动的字符,是以先进先出的方式发送信息的通道.程 ...
- LOG收集系统(一):原日志至收集
Date: 20140207Auth: Jin 设置一个LOG收集系统1. 收集原生(不解析,不压缩)的业务日志和WEB日志(NGINX,PHP)2. 提供给开发,测试直接阅读和下载 需求分析原生日志 ...
- 事件click,bind,click
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- 四.rocketMQ原理
⦁ mqnamesrv服务 broker启动的时候(单个.多个),都会去查找namesrv注册. Producer发生消息的时候会根据topic获取路由到broker的信息. Consumer根 ...
- 未能加载文件或程序集 Version Culture=neutral, PublicKeyToken=
最近项目报错 未能加载文件或程序集"Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, ...
- 二十四种设计模式:备忘录模式(Memento Pattern)
备忘录模式(Memento Pattern) 介绍在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到保存的状态. 示例有一个Message实体类,某 ...