一文彻底解决Android动态权限申请(中)

本文详细介绍了Android 6.0及以上版本动态权限申请的原理和实现,包括所需的关键参数和方法,如Build.VERSION.SDK_INT、PackageManager.PERMISSION_GRANTED等。文章还展示了如何封装权限申请工具类,并提供了权限申请的回调处理和自定义弹窗功能。
摘要由CSDN通过智能技术生成

 

一文彻底解决Android动态权限申请(中)

作者:Lyoun_JAP

关于android动态权限申请的概念和最终实现的android动态权限申请的效果,都在上篇文档《一文彻底解决Android动态权限申请(上)》中有很丰富的体现。

首先说一下android关于动态申请权限需要用到的几个参数和方法,1、app用到的android sdk版本:android.os.Build.VERSION.SDK_INT,我们都知道android动态权限申请是android6.0之后的事情,所以我们在申请权限之前应该坐下判断,只有当android.os.Build.VERSION.SDK_INT > 22时我们才进行动态权限判断。2、PackageManager.PERMISSION_GRANTED,它的值为0,它表示它检查的那个权限是不是已经被授权了,如果值为0则表示已授权,则app不用再重复授权了,若值为-1则说明有权限还没有被授予,这时候就必须要动态申请权限了。3、ActivityCompat.checkSelfPermission(permission),该方法用于判断某个单一权限是否被授权,返回值如果为0,则授权成功。

4、ActivityCompat.shouldShowRequestPermissionRationale(permission),如果某个权限没有被授权时调用,表明app希望获取某个权限。

5、ActivityCompat.requestPermissions(permissions[]),permissions是个权限组,表明一次直接对一组权限进行授权。

6、onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults),该方法是activity中的关于权限设置的回调接口,我们可以通过它来判断我申请的权限是否被授权成功了,如果某些必要权限没有被授予,我们可以自定义弹窗提示用户来进行授权,该方法的三个参数分别对应着requestCode权限请求码,这个与requestPermissions()方法或shouldShowRequestPermissionRationale()方法中的requestCode一一对应,它标识的是对哪一个权限申请的响应,permissions是你申请的权限组,grantResults是针对于你提交的权限组的每个权限的响应,grantResults数组的长度和permissions数组的长度相等。

好了,关于android动态权限申请的api已经介绍完了,下面我着重介绍下我的工程结构,非常简单,如下图就只有两个类,外加一个xml布局文件和AndroidManifest.xml配置文件,

 

其中关于动态权限申请这块我封装成了一个工具类MyPermissionsUtil,我们可以看下它的代码:

//STORAGE 存储卡文件读写权限组
public final static int requestCode_storage = 100;
public static String permissions_storage[] = new String[]{
        "android.permission.WRITE_EXTERNAL_STORAGE",
        "android.permission.READ_EXTERNAL_STORAGE"
};

//MICROPHONE 麦克风权限组
public final static int requestCode_audio = 101;
public static String permissions_audio[] = new String[]{
        "android.permission.RECORD_AUDIO"
};


//CAMERA 相机权限组
public final static int requestCode_camera = 102;
public static String permissions_camera[] = new String[]{
        "android.permission.CAMERA"
};

//LOCATION 位置权限组
public final static int requestCode_location = 103;
public static String permissions_location[] = new String[]{
        "android.permission.ACCESS_FINE_LOCATION",
        "android.permission.ACCESS_COASE_LOCATION"
};

//PHONE 手机权限组
public final static int requestCode_phone = 104;
public static String permissions_phone[] = new String[]{
        "android.permission.READ_PHONE_STATE",
        "android.permission.CALL_PHONE",
        "android.permission.READ_CALL_LOG",
        "android.permission.WRITE_CALL_LOG"
};

//CALENDAR 日历权限组
public final static int requestCode_calendar = 105;
public static String permissions_calendar[] = new String[]{
        "android.permission.READ_CALENDAR",
        "android.permission.WRITE_CALENDAR"
};

//CONTACTS 联系人权限组
public final static int requestCode_contacts = 106;
public static String permissions_contacts[] = new String[]{
        "android.permission.READ_CONTACTS",
        "android.permission.WRITE_CONTACTS",
        "android.permission.GET_ACCOUNTS"
};

//SMS 短信权限组
public final static int requestCode_sms = 107;
public static String permissions_sms[] = new String[]{
        "android.permission.SEND_SMS",
        "android.permission.RECEIVE_SMS",
        "android.permission.READ_SMS",
        "android.permission.RECEIVE_WAP_PUSH"
};

//BODY_SENSORS 传感器权限组
public final static int requestCode_sensors = 108;
public static String permissions_sensors[] = new String[]{
        "android.permission.BODY_SENSORS"
};

public final static int requestCode_all = 109;
public static int granted = PackageManager.PERMISSION_GRANTED;

如上表,我把所有需要动态申请的权限都归并封装成了对应的九大权限数组,分别是STORAGE 存储卡文件读写权限组,MICROPHONE 麦克风录音权限,CAMERA 相机权限组,LOCATION 位置权限组,PHONE 手机权限组,CALENDAR 日历权限组,CONTACTS 联系人权限组,SMS 短信权限组,BODY_SENSORS 传感器权限组,他们对应的requestCode分别为100~108,同时我还设置了个全局变量int granted = PackageManager.PERMISSION_GRANTED;等下做权限判断是需要用到。

然后的话是定义必须要授予的权限,即要使你的app能够正常使用,不得不同意的权限,这个就是等下自定义弹窗的依据。如下表:

//mustGrantedPermiss,必须要授予的权限,如果没有授予这些权限,则提示用户必须要授权后,app才能正常用
public static String[] mustGrantedPermiss = Splicing(permissions_storage, permissions_audio
        , permissions_camera,
        permissions_location,
        permissions_phone,
        permissions_calendar,
        permissions_contacts,
        permissions_sms,
        permissions_sensors
        );

如上表所示,mustGrantedPermiss[]数组就是你应用中必须要授予的权限,你可以按需设置,如果你只需要文件读写权限,则你写入文件读写权限组就好了,其它的可以不写。该权限组可以任意搭配。注意到上表中有一个Splicing()方法,这是我定义的一个用于把字符串数组进行拼接,并最终归结到一个字符串数组里面的方法,完整的方法名是这样:Splicing(String[] checks1, String[]... args),第一个参数指的是你的mustGrantedPermiss[]中的第一个需要申请的权限组,然后后面的args是可长数组,你后面需要跟几个判断权限组,就直接再后面添加就好了,如果就需要判断一个权限组,则args直接设置为null即可。

然后是checkPermissions(Activity activity, String[] needChecks, int requestCode)方法,它是一个最简单的权限申请方法,他一次只能申请一个权限,在需要同时申请多个权限组的情况下时,他不适用。他的代码为:

public void checkPermissions(Activity activity, String[] needChecks, int requestCode) {
    this.mActivity = activity;
    this.mRequestCode = requestCode;

    if (needChecks != null && needChecks.length > 0) {
        //权限检查,只有android6.0及其以上才需要动态权限检查
        if (android.os.Build.VERSION.SDK_INT > 22) {
            for (int i = 0; i < needChecks.length; i++) {
                if (mActivity.checkSelfPermission(needChecks[i]) != granted) {
                    System.out.println("您缺少" + needChecks[i] + "权限,需要动态添加权限");
                    //requestCode 请求码,表明当前是对哪个权限的请求
                  ActivityCompat.requestPermissions(mActivity, needChecks, requestCode);
                    break;
                }
            }
        }
    }
}

 

接着我们将重头戏,能够同时请求多组权限数组的方法,如下表:

boolean storagesGranted = false; //表明该权限是否已被授权
boolean audiosGranted = false;
boolean camerasGranted = false;
boolean locationsGranted = false;
boolean phonesGranted = false;
boolean calendarsGranted = false;
boolean contactsGranted = false;
boolean smsGranted = false;
boolean sensorsGranted = false;

String[] checkStorages = null; //表明客户端有没有请求授予该权限
String[] checkAudios = null;
String[] checkCameras = null;
String[] checkLocations = null;
String[] checkPhones = null;
String[] checkCalendars = null;
String[] checkContacts = null;
String[] checkSms = null;
String[] checkSensors = null;

int storagesDenyed = 0; //表明当前权限有没有被用户拒绝
int audiosDenyed = 0;
int camerasDenyed = 0;
int locationsDenyed = 0;
int phonesDenyed = 0;
int calendarsDenyed = 0;
int contactsDenyed = 0;
int smsDenyed = 0;
int sensorsDenyed = 0;

public static int compareCount = 0;
public static int needCompareCount = 0;

/**
 * @param activity
 * @param checkStorages  //存储卡文件读写权限组
 * @param checkAudios    //麦克风录音权限
 * @param checkCameras   //相机权限组
 * @param checkLocations //位置权限组
 * @param checkPhones    //手机权限组
 * @param checkCalendars //日历权限组
 * @param checkContacts  //联系人权限组
 * @param checkSms       //短信权限组
 * @param checkSensors   //传感器权限组
 */
public void checkMorePermissions(Activity activity,
                                 String[] checkStorages,
                                 String[] checkAudios,
                                 String[] checkCameras,
                                 String[] checkLocations,
                                 String[] checkPhones,
                                 String[] checkCalendars,
                                 String[] checkContacts,
                                 String[] checkSms,
                                 String[] checkSensors) {
    this.mActivity = activity;
    this.checkStorages = checkStorages;
    this.checkAudios = checkAudios;
    this.checkCameras = checkCameras;
    this.checkLocations = checkLocations;
    this.checkPhones = checkPhones;
    this.checkCalendars = checkCalendars;
    this.checkContacts = checkContacts;
    this.checkSms = checkSms;
    this.checkSensors = checkSensors;

    //把数据初始化
    storagesDenyed = 0;
    audiosDenyed = 0;
    camerasDenyed = 0;
    locationsDenyed = 0;
    phonesDenyed = 0;
    calendarsDenyed = 0;
    contactsDenyed = 0;
    smsDenyed = 0;
    sensorsDenyed = 0;

    compareCount = 0;
    needCompareCount = 0;

    if(checkStorages != null && checkStorages.length > 0){
        needCompareCount++;
    }
    if(checkAudios != null && checkAudios.length > 0){
        needCompareCount++;
    }
    if(checkCameras != null && checkCameras.length > 0){
        needCompareCount++;
    }
    if(checkLocations != null && checkLocations.length > 0){
        needCompareCount++;
    }
    if(checkPhones != null && checkPhones.length > 0){
        needCompareCount++;
    }
    if(checkCalendars != null && checkCalendars.length > 0){
        needCompareCount++;
    }
    if(checkContacts != null && checkContacts.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值