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 或更高版本对权限 ...
随机推荐
- 将Electron桌面应用转化为Win10的UWP应用
如果有小伙伴不知道如何打包Electron桌面应用的,请戳我. 微软提供了一款快捷工具:electron-windows-store,用于将electron桌面应用打包成Windows10系统上.ap ...
- 关于 CommonJS AMD CMD UMD
1. CommonJS CommonJS 原来叫 ServerJS, 是服务器端模块的规范,Node.js采用了这个规范. 根据CommonJS规范,一个单独的文件就是一个模块.加载模块使用requi ...
- 【最短路】NOIP模拟赛 虫洞
虫洞 [题目描述] N个虫洞,M条单向跃迁路径.从一个虫洞沿跃迁路径到另一个虫洞需要消耗一定量的燃料和1单位时间.虫洞有白洞和黑洞之分.设一条跃迁路径两端的虫洞质量差为delta. 1. 从白洞跃迁到 ...
- BZOJ 3669 [Noi2014]魔法森林(贪心+LCT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3669 [题目大意] 给出一张图,每条边上有两个值ai和bi,现在需要求出一条1到N的路 ...
- android系统各种音量的获取与设置
获取系统音量 通过程序获取android系统手机的铃声和音量.同样,设置铃声和音量的方法也很简单! 设置音量的方法也很简单,AudioManager提供了方法: publicvoidsetStream ...
- [转] javax.servlet.jar - jar not loaded问题解决
把那个jsp-api.jarservlet-api.jar删除即可! Details:把 webapps\maintenance\WEB-INF\lib\ 下面的 servlet-api.jar 删掉 ...
- while an existing transition or presentation is occurring; the navigation stack will not be updated
使用UIAlertController提示信息,在之后使用navigation进行逻辑跳转时,出现popToViewController:transition: called on <UINav ...
- maven-忽略文件-.gitignore文件
# kdiff3 ignore *.orig # maven ignore target/ # eclipse ignore .settings/ .project .classpath # idea ...
- 使用MailKit收发邮件
.Net BCL库中对于邮件的支持只有SmtpClient一个,它只能进行简单的邮件的发送操作,并且不支持POP3和SMTP,无法接收邮件,用起来有诸多不便. 今天看到园子里有文章(使用 MimeKi ...
- winform窗体MaximizeBox
如果MaximizeBox为false会导致Form2窗体底部不显示. =>解决办法TopMost属性为true. Form2 _frm2 = new Form2(); _frm2.Maximi ...