您的位置:首页 > 移动开发 > Android开发

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();
}


如果帮到你了,就给我一个赞吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息