android6.x运行时权限申请管理
2016-10-26 14:51
429 查看
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">android6.x后,对一些级别比较重要的权限(级别为dangerous),需要在运行时都动态的请求授权,具体的步骤比较简单,如下几步:</span>
在AndroidManifest文件中添加需要的权限。
不管是什么级别的,都要在文件中添加上。
检查权限
if (ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.READ_CONTACTS)!=
PackageManager.PERMISSION_GRANTED) {
}else{
//do something
}
申请授权
ActivityCompat.requestPermissions(thisActivity,new
String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。第二个参数是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权。
处理权限申请回调
@Override
publicvoid
onRequestPermissionsResult(int requestCode,
String permissions[],int[]
grantResults) {
switch (requestCode) {
case
MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result
arrays are empty.
if
(grantResults.length > 0&& grantResults[0]
== PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
}else
{
// permission denied, boo! Disable the
// functionality that depends on this
permission.
}
return;
}
}
}
首先验证requestCode定位到你的申请,然后验证grantResults对应于申请的结果,这里的数组对应于申请时的第二个权限字符串数组。如果你同时申请两个权限,那么grantResults的length就为2,分别记录你两个权限的申请结果。
如果用户拒绝的时候选择了不再提醒,那么下一次用户点击的时候,就不会弹出确认权限的提示了,这样App 就什么也不做了,UI体验不好。可以用下面的方法给用户一个提示:
只有当用户在上一次选择了不再提醒并点击拒绝后,此方法会返回false,
因此if里面要取反
// Should we show an explanation?
if
(!ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.READ_CONTACTS)){
// Show an expanation to the user *asynchronously*
-- don't block
// this thread waiting for the user's
response! After the user
// sees the explanation, try again to
request the permission.
}
运行时的权限申请就是以上这几部,代码很简单,但是需要编写大量重复的代码,于是根据公司的业务,我自己封装了一个类,RuntimePermissionManager。具体的用法在代码注释里面了。
RuntimePermissionManager.java:
package com.xiaxiao.runtimepermissionsmanager; /** * 运行时权限管理类,针对安卓6.x版本 * 对运行时的权限申请进行了分装 * * 用法1: * * 在BaseActivity中声明 RuntimePermissionManager r 变量, *创建方法 public RuntimePermissionsManager getRuntimePermissionManager(Activity activity) { *if (runtimePermissionsManager==null) { *runtimePermissionsManager = new RuntimePermissionsManager(activity); *} *return runtimePermissionsManager; *} *继承方法 onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, *@NonNull int[] grantResults),在其中调用如下方法即可。 *runtimePermissionsManager.handle(requestCode, permissions, grantResults); *然后在BaseActivity的子类中通过通过创建r实例和r.workWithPermission(String ,Callback), *具体的业务逻辑<b>需且只需</b>实现Callbakc接口既可。 * * 方法2: * * 如果没有baseActivity父类,则需在当前Activity中声明RuntimePermissionManager r变量, * 并通过 r=new RuntimePermissionManager(thisActivity) * 创建实例, * 然后重写本类的onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, *@NonNull int[] grantResults),在其中调用如下方法即可。 *runtimePermissionsManager.handle(requestCode, permissions, grantResults); * 其它步骤如上。 * * * */ import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import java.util.ArrayList; /** * Created by xiaxiao on 2016/10/20. */ public class RuntimePermissionsManager { private Activity activity; private int requestCode=8888; private RequestCallback requestCallback; /** * 本程序中需要用到的权限 */ private final static String[] requestedPermissions={ Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_SMS, Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_EXTERNAL_STORAGE }; public RuntimePermissionsManager (Activity activity) { this.activity=activity; } /** * 检查所给的权限是否已被授权 * @param permission 要检查的权限名字 * @return true:已被授权;false:未被授权 */ public boolean checkPermission(String permission) { return permission!=null&&(ContextCompat.checkSelfPermission(activity,permission)== PackageManager.PERMISSION_GRANTED); } /** * 请求授权,限内部调用 * @param permissions 当为null时,表示遍历整个程序需要的权限, * 当不为null时,表示请求传入的权限,此时permissions的有效length是1,其余大于1的权限请求将不会处理 */ private void requestPermissions(String[] permissions) { if (permissions==null) { permissions = requestedPermissions; } //过滤出目前还未被授权的权限 String[] noGrantedPermissions; ArrayList<String> l=new ArrayList<String>(); for (String s:permissions) { if (!checkPermission(s)) { l.add(s); } } if (l.size()==0) { return; } //一次性请求所有未被授权的权限 noGrantedPermissions=(String[])l.toArray(new String[l.size()]); ActivityCompat.requestPermissions(activity, noGrantedPermissions, requestCode); } /** * 请求程序所有运行时需要申请的权限 */ public void requestPermissions() { requestPermissions(null); } /** * 请求指定的单个权限 * @param permission 给定的权限 */ public void requestPermission(String permission) { if (!ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) { showDialog(); } else { requestPermissions(new String[]{permission}); } } /** * 处理权限申请的回调方法 * @param requestCode * @param permissions * @param grantResults */ public void handle(int requestCode,String[] permissions,int[] grantResults) { if (requestCallback==null) { return; } if (requestCode == this.requestCode) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { //Permission success requestCallback.requestSuccess(); } else { // Permission Denied requestCallback.requestFailed(); } } else { // Log.i("error","requestCode not match"); } } /** * 检测权限,如未被授权则申请,并继续处理业务 * @param permission 需要使用的权限 * @param requestCallback 回调类,负责处理具体业务,包含权限已被授权和申请后的情况 */ public void workwithPermission(String permission,RequestCallback requestCallback) { if (permission==null||requestCallback==null) { return; } this.requestCallback=requestCallback; if (checkPermission(permission)) { requestCallback.requestSuccess(); } else { requestPermission(permission); } } public void showDialog(){ AlertDialog dialog = new AlertDialog.Builder(activity) .setMessage("该操作需要被赋予相应的权限,不开启将无法正常工作!") .setPositiveButton("开启", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); Intent i=new Intent(); i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); i.setData(Uri.fromParts("package", activity.getPackageName(), null)); activity.startActivity(i); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).create(); dialog.show(); } interface RequestCallback { public void requestSuccess(); public void requestFailed(); }
如果帮到你了,就给我一个赞吧。
相关文章推荐
- Android开发之运行时权限申请和自定义权限
- 读书笔记--android运行时权限管理最佳实践-我靠一直崩溃是不是因为权限问题
- Android应用申请运行时权限(Permission)示例
- Android 6.0 运行时权限管理最佳实践
- Android 申请运行时权限 以camera为例
- Android 6.0的运行时权限 批量申请
- Android 6.x 运行时权限
- android运行时权限解决办法(含有申请权限已授权、权限被拒绝、权限勾选不在提示的回调)
- Android M 6.0以上 需要运行时申请的权限--easypermissions库
- Android 6.0 运行时在Fragment中申请权限无法回调 问题
- android运行时权限解决办法(含有申请权限已授权、权限被拒绝、权限勾选不在提示的回调)
- Android 6.0 运行时权限管理最佳实践
- Android权限管理之Android 6.0运行时权限及解决办法
- Android 6.0 运行时权限管理最佳实践
- android 6.0运行时权限的申请(微信在android 6.0上实现运行时请求权限的实现)
- Android 6.0 运行时权限管理
- 【Android】6.0 运行时权限申请
- Android权限管理之Android 6.0运行时权限及解决办法
- Android 6.0以上 需要运行时申请的权限(一)
- Android 6.0运行时权限解析与申请