android6.x运行时权限申请管理

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">android6.x后,对一些级别比较重要的权限(级别为dangerous),需要在运行时都动态的请求授权,具体的步骤比较简单,如下几步:</span>


  1. 在AndroidManifest文件中添加需要的权限。
不管是什么级别的,都要在文件中添加上。
  1. 检查权限
if (ContextCompat .checkSelfPermission (thisActivity,Manifest .permission.READ _CONTACTS)!= PackageManager .PERMISSION _GRANTED) {
}else{ 
//do something
}

  1. 申请授权
ActivityCompat .requestPermissions (thisActivity,new String[]{Manifest .permission.READ _CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS) ;

第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。 第二个参数是支持一次性申请多个权限的,系统会通过对话框 逐一 询问用户是否授权。
  1. 处理权限申请回调
@Override
public void 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();
    }


如果帮到你了,就给我一个赞吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值