前言

android6.0開始,权限的申请发生了改变,申请变的动态化,也就是执行时权限,和iOS相仿,动态化的意思是指,在每次使用须要危急权限的方法的时候。须要检查程序是否获得了该权限的许可。动态化的权限申请能够让用户更加清晰的知道程序须要什么权限。以及程序中哪些地方的操作须要涉及用户安全。

不再是只在程序安装的时候,一次性把所须要的普通的、危急级别的权限一次性列出来。然后展示给用户。

当project项目的target Sdk为23时,因为考虑到用户假设没有进行权限的动态检查,那么在执行到须要权限的代码时,会发生crash。而当你的target Sdk为23下面时,则不强制要求权限的动态监測,此时app不会crash。还是能够正常的使用功能。

Google官网上动态申请权限的方法分了在Activity和Fragment这两种,通过ContextCompat以及子类,ActivityCompat和FragmentCompat去进行权限的申请和权限的检查,而申请的方式是弹出一个系统的不能够改写的对话框。结果是通过Activity和Fragment的onRequestPermissionResult()方法进行返回。
详细能够參考官网

可是这样的代码会促使以前的project进行大改造或者说代码的逻辑会耦合的写在同一个方法里。显的不方便和臃肿。

所以下面的EasyPermissionUtil就是简化权限请求的方式,同一时候能够使代码的逻辑更加清晰。

EasyPermissionUtil:简化权限请求

因为权限的请求和结果的返回须要分开Activity和Fragment两种去进行操作,这样会比較麻烦,所以EasyPermissionUtil中投机取巧,通过开启一个新的activity进行权限申请和检查的操作。这样不用去区分多种情况,同一时候也能够把全部的申请过程和结果统一由EasyPermissionUtil进行处理。
接下来看一下总体的思想:

使用的方法

PermissionUtil.getInstance().request(MainActivity.this, new String[]{Manifest.permission.READ_CALENDAR}, mRequestCode,new PermissionResultCallBack() {@Overridepublic void onPermissionGranted() {// 当全部权限的申请被用户允许之后,该方法会被调用}@Overridepublic void onPermissionDenied(String... permissions) {// 当权限申请中的某一个或多个权限,被用户以前否定了,并确认了不再提醒时,也就是权限的申请窗体不能再弹出时,该方法将会被调用}@Overridepublic void onRationalShow(String... permissions) {// 当权限申请中的某一个或多个权限,被用户否定了,但没有确认不再提醒时,也就是权限窗体申请时,但被否定了之后,该方法将会被调用.}});

项目源代码下载以及介绍。请看github。

项目源代码

在PermissionUtil中,要做的是:
1.进行权限检查
2.没有得到权限许可的进行权限申请
3.返回权限申请的结果

public class PermissionUtil {private PermissionResultCallBack mPermissionResultCallBack;private volatile static PermissionUtil instance;private int mRequestCode;private Context mContext;private Fragment mFragment;private List<PermissionInfo> mPermissionListNeedReq;private String[] mPermissions;public static PermissionUtil getInstance() {if (instance == null) {synchronized (PermissionUtil.class) {if (instance == null) {instance = new PermissionUtil();}}}return instance;}/*** 用于fragment中请求权限* @param fragment* @param permissions* @param requestCode* @param callBack*/public void request(@NonNull Fragment fragment,@NonNull String[] permissions,@NonNull int requestCode, PermissionResultCallBack callBack) {this.mFragment = fragment;this.request(fragment.getActivity(), permissions, requestCode, callBack);}/*** 用于activity中请求权限* @param context* @param permissions* @param requestCode* @param callBack*/public void request(@NonNull Context context,@NonNull String[] permissions,@NonNull int requestCode, PermissionResultCallBack callBack) {if (Looper.myLooper() != Looper.getMainLooper()) {throw new RuntimeException("request permission only can run in MainThread!");}if (permissions.length == 0) {return;}if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {onGranted();return;}this.mContext = context;this.mPermissions = permissions;this.mRequestCode = requestCode;this.mPermissionResultCallBack = callBack;this.mPermissionListNeedReq = new ArrayList<PermissionInfo>();if (needToRequest()) {requestPermissions();} else {onGranted();}}/*** 通过开启一个新的activity作为申请权限的媒介*/private void requestPermissions() {Intent intent = new Intent(mContext, HelpActivity.class);intent.putExtra("permissions", mPermissions);intent.putExtra("requestCode", mRequestCode);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mContext.startActivity(intent);}/*** 检查是否须要申请权限* @return*/private boolean needToRequest() {for (String permission : mPermissions) {int checkRes = ContextCompat.checkSelfPermission(mContext, permission);if (checkRes != PackageManager.PERMISSION_GRANTED) {PermissionInfo info = new PermissionInfo(permission);if (mContext instanceof Activity &&ActivityCompat.shouldShowRequestPermissionRationale((Activity) mContext, permission)) {info.setRationalNeed(true);}mPermissionListNeedReq.add(info);}}if (mPermissionListNeedReq.size() > 0) {mPermissions = new String[mPermissionListNeedReq.size()];for (int i = 0; i < mPermissionListNeedReq.size(); i++) {mPermissions[i] = mPermissionListNeedReq.get(i).getName();}return true;}return false;}/*** 申请权限结果返回* @param requestCode* @param permissions* @param grantResults*/@TargetApi(Build.VERSION_CODES.M)protected void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {if (requestCode == mRequestCode) {if (mContext != null && mContext instanceof Activity) {((Activity) mContext).onRequestPermissionsResult(requestCode, permissions, grantResults);}if (mFragment != null) {mFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);}boolean isAllGranted = true;List<PermissionInfo> needRationalPermissionList = new ArrayList<PermissionInfo>();List<PermissionInfo> deniedPermissionList = new ArrayList<PermissionInfo>();for (int i = 0; i < permissions.length; i++) {if (grantResults[i] == PackageManager.PERMISSION_DENIED) {if (mPermissionListNeedReq.get(i).isRationalNeed()) {needRationalPermissionList.add(mPermissionListNeedReq.get(i));} else {deniedPermissionList.add(mPermissionListNeedReq.get(i));}isAllGranted = false;}}if (needRationalPermissionList.size() != 0) {showRational(needRationalPermissionList);}if (deniedPermissionList.size() != 0) {onDenied(deniedPermissionList);}if (isAllGranted) {onGranted();}}}/*** 权限被用户许可之后回调的方法*/private void onGranted() {if (mPermissionResultCallBack != null) {mPermissionResultCallBack.onPermissionGranted();}}/*** 权限申请被用户否定之后的回调方法,这个主要是当用户点击否定的同一时候点击了不在弹出,* 那么当再次申请权限,此方法会被调用* @param list*/private void onDenied(List<PermissionInfo> list) {if(list == null || list.size() == 0) return;String[] permissions = new String[list.size()];for (int i = 0; i < list.size(); i++) {permissions[i] = list.get(i).getName();}if (mPermissionResultCallBack != null) {mPermissionResultCallBack.onPermissionDenied(permissions);}}/*** 权限申请被用户否定后的回调方法,这个主要场景是当用户点击了否定,但未点击不在弹出,* 那么当再次申请权限的时候,此方法会被调用* @param list*/private void showRational(List<PermissionInfo> list) {if(list == null || list.size() == 0) return;String[] permissions = new String[list.size()];for (int i = 0; i < list.size(); i++) {permissions[i] = list.get(i).getName();}if (mPermissionResultCallBack != null) {mPermissionResultCallBack.onRationalShow(permissions);}}}

在PermissionResutCallBack中,要做的是:
1.返回相应的结果

public interface PermissionResultCallBack {/*** 当全部权限的申请被用户允许之后,该方法会被调用*/void onPermissionGranted();/*** 当权限申请中的某一个或多个权限,被用户以前否定了,并确认了不再提醒时,也就是权限的申请窗体不能再弹出时,* 该方法将会被调用* @param permissions*/void onPermissionDenied(String... permissions);/*** 当权限申请中的某一个或多个权限,被用户否定了,但没有确认不再提醒时,也就是权限窗体申请时,但被否定了之后,* 该方法将会被调用.* @param permissions*/void onRationalShow(String... permissions);
}

在HelpActivity中。要做的就是:
1.申请权限
2.通过onRequestPermissionUtil返回结果给PermissionUtil
当然这个activity必须是透明的,并且是没有不论什么的view的。这样看起来才不像是开了一个新的activity。

public class HelpActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (savedInstanceState == null) {handleIntent(getIntent());}}@Overrideprotected void onNewIntent(Intent intent) {handleIntent(intent);}// 权限申请@TargetApi(Build.VERSION_CODES.M)private void handleIntent(Intent intent) {String[] permissions = intent.getStringArrayExtra("permissions");int requestCode = intent.getIntExtra("requestCode", 42);ActivityCompat.requestPermissions(this, permissions, requestCode);}@Overrideprotected void onDestroy() {super.onDestroy();}// 返回结果@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {PermissionUtil.getInstance().onRequestPermissionResult(requestCode, permissions, grantResults);finish();}
}

项目源代码下载以及介绍。请看github。

android6.0权限管理工具EasyPermissionUtil相关推荐

  1. android拍照所需的权限,eclipse --- Android拍照,相册选择图片以及Android6.0权限管理...

    [实例简介] eclipse --- Android拍照,相册选择图片以及Android6.0权限管理 [实例截图] [核心代码] camreainandroidm └── camreainandro ...

  2. android关闭权限管理,Android6.0权限管理以及使用权限该注意的地方

    Android 6.0 Marshmallow首次增加了执行时权限管理,这对用户来说,能够更好的了解.控 制 app 涉及到的权限.然而对开发人员来说却是一件比較蛋疼的事情.须要兼容适配,并保证程序功 ...

  3. Android6.0权限管理-PermissionsDispatcher

    请查看我的个人网站 新的运行时权限仅当我们设置targetSdkVersion to 23才起作用,app在6.0之前的设备依然使用旧的权限系统. 如果app的targetSdkVersion 低于 ...

  4. Android M Android6.0 权限管理 EasyPermission Demo

    https://github.com/louisgeek/LouisEasyPermission

  5. Android6.0权限大全和权限分类

    自从出了Android6.0权限管理之后,再也不能像以前那样粘贴复制了,必须认识权限了,所以总结一下方便以后自己使用. 一.所有权限 访问登记属性 android.permission.ACCESS_ ...

  6. android 7.0 自启管理,一款不错的android6.0、7.0权限管理器推荐

    一款不错的android6.0.7.0权限管理器PermissionsCheckerUtil 初始化权限管理器:构造方法 private final Context mContext; public ...

  7. Android6.0权限适配及兼容库的实现

    从6.0 MarshMallow开始,Android支持动态权限管理,即有些权限需要在使用到的时候动态申请,根据用户的选择需要有不同的处理,具体表现可以看下图: 本文并不关心权限适配的原理,原理可以参 ...

  8. android 6.0 短信权限,Android6.0权限适配

    Code4Android .jpg 前言 现在谈论Android权限适配可能有点没必要,因为网上关于权限适配的文章很多,搜一下Android6.0权限适配关键词能搜到一堆文章,而且很多写的还很不错.不 ...

  9. Android6.0M权限管理实战,完美轻量级封装

    Android6.0M权限管理实战,完美轻量级封装 随着Android版本的不断更新,Google的Android开发人员也想到了Android应用在权限管理方面的各种问题,让好多用户摸不着头脑就使用 ...

最新文章

  1. 高考计算机算分么,高考分数是怎么算出来的
  2. Node mysql
  3. AndroidMainfest.xml具体解释——lt;activitygt;
  4. KITTI数据集评估方法小结
  5. 小米路由器青春版刷潘多拉、华硕固件
  6. python开发_filecmp
  7. NoteExpress
  8. Python爬虫获取异步加载站点pexels并下载图片(Python爬虫实战3)
  9. 使用Rosetta批量生成fasta
  10. 04.TFT_RGB接口时序分析
  11. 计算机桌面图标怎么显示出来,显示桌面图标不见了怎么办?显示桌面图标不见了解决方法...
  12. 破解Redhat开机密码过程
  13. 微服务架构最重要的 10 个设计模式!
  14. 王者4K高清壁纸合集
  15. 微信网址防封防屏蔽,微信域名一直被封怎么办
  16. 腾讯云增值税发票OCR
  17. 能源结构优化与低碳化发展:低碳化指数-全国分地区能源消费结构
  18. 网络大学统考计算机是不是文管二级,河南省大学计算机等级考试选择题(文管二级)...
  19. 使用 CSS 的仿 GitHub 登录页面
  20. 区块链技术在IoT领域的应用综述

热门文章

  1. 去除网页上图片的虚框和a文字链接上的虚框
  2. 一起来玩树莓派--在docker内安装conda(python3.6)
  3. TS DataType
  4. 理解有参构造器和无参构造器的作用
  5. 计算机网络基础文档,计算机网络基础-20210608152532.pdf-原创力文档
  6. wangeditor 不识别html_前端知识(一)认识HTML
  7. android studio 触摸锁,学习AndroidStudio布局,并编写一个图案解锁demo
  8. 【LOJ】#3123. 「CTS2019 | CTSC2019」重复
  9. python之字典方法
  10. day05 Python 元组