代码地址如下:
http://www.demodashi.com/demo/13506.html

写在前面

上次写了一个权限申请的例子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=0if (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 grantedToast.makeText(MainActivity.this, "onGranted", Toast.LENGTH_SHORT).show();}, () -> {// on deniedToast.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)

代码地址如下:
http://www.demodashi.com/demo/13506.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

Android 6.0 超级简单的权限申请2 (Permission)相关推荐

  1. Android 6.0 超级简单的权限申请 (Permission)

    代码地址如下: http://www.demodashi.com/demo/13369.html 背景描述 随着Android系统的不断升级,谷歌对用户的隐私是越来越注重了,给我们开发者带来了更多的繁 ...

  2. API 23之前的版本都是自动获取权限,而从 Android 6.0 开始添加了权限申请的需求,更加安全。

    这里以单个存储权限为例: · 在 Manifest 中添加访问权限:(只需设置可写,因为可写必定可读) <uses-permission android:name="android.p ...

  3. android 6.0 api 管理,Android 6.0(API23)权限申请问题

    1.在API23+以上,不止要在AndroidManifest.xml里面添加权限 2.还要在JAVA代码中请求权限: // Storage Permissions private static fi ...

  4. Android9获取权限闪退,Android 9.0 关于ACTION_CALL无权限导致闪退的问题

    Android 9.0 关于ACTION_CALL无权限导致闪退的问题 18年年底毕业,开始从事android研发,对application层有兴趣,于是自学使用Android studio对app的 ...

  5. android 权限作用说明书,AndroidAcp 一句话搞定,简化 Android 6.0 系统复杂的权限操作 @codeKK Android开源站...

    Acp 为 Android check permission 缩写,此库简化 Android 6.0 系统复杂的权限操作而编写. 特点 支持批量权限申请,不需要重写 onRequestPermissi ...

  6. linux录音设备权限,Android 6.0 之前的录音权限问题

    Android 6.0 之前的录音权限问题 Android,权限,录音 2018.08.13 Android 6.0 提出了新的权限管理机制.而在 6.0 之前,各个厂商也搞了一些自己的权限管理机制, ...

  7. 原生Android之(6.0及以上)权限申请

    为什么Android的要申请权限 简单说下在Android6.0及6.0以上一些谷歌认为涉及"危险和用户隐私"的一些权限不仅要做清单文件(机器人/应用/ SRC / Android ...

  8. android申请权限一次性申请多个,android 6.0以上动态一次申请多个权限-最美解决方案...

    目录 背景 危险权限 申请权限思路 申请权限流程 干货 后续 一.背景 android23 API新增危险权限校验,需要手动获取: 二.危险权限: 日历数据 android.permission-gr ...

  9. 聊一聊Android 6.0的运行时权限

    Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...

最新文章

  1. php get memory,PHP memory_get_usage 和 memory_get_peak_usage获取内存的区别
  2. python3操作MySQL:insert插入数据
  3. Oracle 11G 64位发布出现错误
  4. Java三种类型之间的转换方法:Date、String、Calendar类型之间的转化
  5. java 发送 json数据_Java web中怎样取得Android通过post发送的json数据
  6. 事务对性能影响_mysql之事务
  7. Matlab 绘制箱线图
  8. c语言构造数学模型步骤,数学建模的6个基本步骤
  9. HMI智能座舱自动化测试软件
  10. html 网页配色,配色就是这么简单!7个在线配色网站推荐
  11. 论文笔记:SAIN: Self-Attentive Integration Network for Recommendation(SIGIR 2019)
  12. 进程系列(一)-进程基本概念
  13. Go语言%d,%p,%v等占位符
  14. python的PIL库部分模块函数
  15. 怎样用excel按进行分类求和,最后再根据一列对其他列进行排序
  16. Java练习案例之输入一个字符串统计每个字母出现次数
  17. 【进程间通信】进程间通信方式汇总
  18. 蓝队工具:使用VirusTotal API校验样本
  19. 方案设计阶段目标成本形成过程
  20. 力扣解题思路:位运算系列

热门文章

  1. DataInputStream与DataOutputStream类
  2. android activity 被notification启动,Android通知Notification全面剖析
  3. 内蒙古计算机专修学院单招,内蒙古电子信息职业技术学院单招多少分能上?
  4. python从mysql导出大量数据_python批量导出导入MySQL用户的方法
  5. mysql clob转string_Java获取Oracle中CLOB字段转换成String
  6. android webview 获取网页内容,在WebView中获取网页中的内容
  7. 基于threejs的商场楼层展示导航系统源码_便民措施再升级就诊无需问路!我院“智能导航系统”正式上线啦!...
  8. 手机和Linux蓝牙通信,[原创]linux下手机与蓝牙的连接配置
  9. python模拟键盘输入_python模拟键盘输入的问题
  10. oracletns中不存在名称为_oracle tnsname.ora中的SERVICE_NAME 代表实例的名称还是代表全局数据库的名称?...