一文彻底解决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;/***@paramactivity*@paramcheckStorages//存储卡文件读写权限组*@paramcheckAudios//麦克风录音权限*@paramcheckCameras//相机权限组*@paramcheckLocations//位置权限组*@paramcheckPhones//手机权限组*@paramcheckCalendars//日历权限组*@paramcheckContacts//联系人权限组*@paramcheckSms//短信权限组*@paramcheckSensors//传感器权限组*/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.length > 0){ needCompareCount++; } if(checkSms != null && checkSms.length > 0){ needCompareCount++; } if(checkSensors != null && checkSensors.length > 0){ needCompareCount++; } //权限检查,只有android6.0及其以上才需要动态权限检查 if (android.os.Build.VERSION.SDK_INT> 22) { try { if (checkStorages != null && checkStorages.length > 0) { int i = 0; for (; i < checkStorages.length; i++) { if (mActivity.checkSelfPermission(checkStorages[i]) != granted) { System.out.println("您缺少" + checkStorages[i] + "权限,需要动态添加权限"); //requestCode请求码,表明当前是对哪个权限的请求 storagesGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkStorages, requestCode_storage); break; } } if (i == checkStorages.length) { storagesGranted = true; if(needCompareCount> 0){ needCompareCount--; } } } if (checkAudios != null && checkAudios.length > 0 && checkStorages != null && (storagesGranted || !(checkStorages != null && checkStorages.length > 0))) {// int i = 0; for (; i < checkAudios.length; i++) { if (mActivity.checkSelfPermission(checkAudios[i]) != granted) { System.out.println("您缺少" + checkAudios[i] + "权限,需要动态添加权限"); //requestCode请求码,表明当前是对哪个权限的请求 audiosGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkAudios, requestCode_audio); break; } } if (i == checkAudios.length) { audiosGranted = true; if(needCompareCount> 0){ needCompareCount--; } } } if (checkCameras != null && checkCameras.length > 0 && (storagesGranted || !(checkStorages != null && checkStorages.length > 0)) && (audiosGranted || !(checkAudios != null && checkAudios.length > 0))) { int i = 0; for (; i < checkCameras.length; i++) { if (mActivity.checkSelfPermission(checkCameras[i]) != granted) { System.out.println("您缺少" + checkCameras[i] + "权限,需要动态添加权限"); //requestCode请求码,表明当前是对哪个权限的请求 camerasGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkCameras, requestCode_camera); break; } } if (i == checkCameras.length) { camerasGranted = true; if(needCompareCount> 0){ needCompareCount--; } } } if (checkLocations != null && checkLocations.length > 0 && !locationsGranted && (storagesGranted || !(checkStorages != null && checkStorages.length > 0)) && (audiosGranted || !(checkAudios != null && checkAudios.length > 0)) && (camerasGranted || !(checkCameras != null && checkCameras.length > 0))) { int i = 0; for (; i < checkLocations.length; i++) { System.out.println("location: " + i + " : " + checkLocations[i] + "," + mActivity.checkSelfPermission(checkLocations[i])); if (mActivity.checkSelfPermission(checkLocations[i]) == granted) { //requestCode请求码,表明当前是对哪个权限的请求 locationsGranted = true; if(needCompareCount> 0){ needCompareCount--; } break; } } if (i == checkLocations.length && !locationsGranted) { System.out.println("why location: " + i + "," + checkLocations.length + "," + locationsGranted); locationsGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkLocations, requestCode_location); } } if (checkPhones != null && checkPhones.length > 0 && !phonesGranted && (storagesGranted || !(checkStorages != null && checkStorages.length > 0)) && (audiosGranted || !(checkAudios != null && checkAudios.length > 0)) && (camerasGranted || !(checkCameras != null && checkCameras.length > 0)) && (locationsGranted || !(checkLocations != null && checkLocations.length > 0))) {// int i = 0; for (; i < checkPhones.length; i++) { if (mActivity.checkSelfPermission(checkPhones[i]) != granted) { System.out.println("您缺少" + checkPhones[i] + "权限,需要动态添加权限"); //requestCode请求码,表明当前是对哪个权限的请求 phonesGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkPhones, requestCode_phone); break; } } if (i == checkPhones.length) { phonesGranted = true; if(needCompareCount> 0){ needCompareCount--; } } } if (checkCalendars != null && checkCalendars.length > 0 && !calendarsGranted && (storagesGranted || !(checkStorages != null && checkStorages.length > 0)) && (audiosGranted || !(checkAudios != null && checkAudios.length > 0)) && (camerasGranted || !(checkCameras != null && checkCameras.length > 0)) && (locationsGranted || !(checkLocations != null && checkLocations.length > 0)) && (phonesGranted || !(checkPhones != null && checkPhones.length > 0))) {//&& (phonesGranted || !(checkPhones != null && checkPhones.length > 0)) int i = 0; for (; i < checkCalendars.length; i++) { if (mActivity.checkSelfPermission(checkCalendars[i]) != granted) { System.out.println("您缺少" + checkCalendars[i] + "权限,需要动态添加权限"); //requestCode请求码,表明当前是对哪个权限的请求 calendarsGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkCalendars, requestCode_calendar); break; } } if (i == checkCalendars.length) { calendarsGranted = true; if(needCompareCount> 0){ needCompareCount--; } } } if (checkContacts != null && checkContacts.length > 0 && !contactsGranted && (storagesGranted || !(checkStorages != null && checkStorages.length > 0)) && (audiosGranted || !(checkAudios != null && checkAudios.length > 0)) && (camerasGranted || !(checkCameras != null && checkCameras.length > 0)) && (locationsGranted || !(checkLocations != null && checkLocations.length > 0)) && (phonesGranted || !(checkPhones != null && checkPhones.length > 0)) && (calendarsGranted || !(checkCalendars != null && checkCalendars.length > 0))) {// int i = 0; for (; i < checkContacts.length; i++) { if (mActivity.checkSelfPermission(checkContacts[i]) != granted) { System.out.println("您缺少" + checkContacts[i] + "权限,需要动态添加权限"); //requestCode请求码,表明当前是对哪个权限的请求 contactsGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkContacts, requestCode_contacts); break; } } if (i == checkContacts.length) { contactsGranted = true; if(needCompareCount> 0){ needCompareCount--; } } } if (checkSms != null && checkSms.length > 0 && !smsGranted && (storagesGranted || !(checkStorages != null && checkStorages.length > 0)) && (audiosGranted || !(checkAudios != null && checkAudios.length > 0)) && (camerasGranted || !(checkCameras != null && checkCameras.length > 0)) && (locationsGranted || !(checkLocations != null && checkLocations.length > 0)) && (phonesGranted || !(checkPhones != null && checkPhones.length > 0)) && (calendarsGranted || !(checkCalendars != null && checkCalendars.length > 0)) && (contactsGranted || !(checkContacts != null && checkContacts.length > 0))) {// int i = 0; for (; i < checkSms.length; i++) { if (mActivity.checkSelfPermission(checkSms[i]) != granted) { System.out.println("您缺少" + checkSms[i] + "权限,需要动态添加权限"); //requestCode请求码,表明当前是对哪个权限的请求 smsGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkSms, requestCode_sms); break; } } if (i == checkSms.length) { smsGranted = true; if(needCompareCount> 0){ needCompareCount--; } } } if (checkSensors != null && checkSensors.length > 0 && !sensorsGranted && (storagesGranted || !(checkStorages != null && checkStorages.length > 0)) && (audiosGranted || !(checkAudios != null && checkAudios.length > 0)) && (camerasGranted || !(checkCameras != null && checkCameras.length > 0)) && (locationsGranted || !(checkLocations != null && checkLocations.length > 0)) && (phonesGranted || !(checkPhones != null && checkPhones.length > 0)) && (calendarsGranted || !(checkCalendars != null && checkCalendars.length > 0)) && (contactsGranted || !(checkContacts != null && checkContacts.length > 0)) && (smsGranted || !(checkSms != null && checkSms.length > 0))) {// int i = 0; for (; i < checkSensors.length; i++) { if (mActivity.checkSelfPermission(checkSensors[i]) != granted) { System.out.println("您缺少" + checkSensors[i] + "权限,需要动态添加权限"); //requestCode请求码,表明当前是对哪个权限的请求 sensorsGranted = false; //needCompareCount++; ActivityCompat.requestPermissions(mActivity, checkSensors, requestCode_sensors); break; } } if (i == checkSensors.length) { sensorsGranted = true; if(needCompareCount> 0){ needCompareCount--; } } } } catch (Exception e) { e.printStackTrace(); } }}
如上表所示,首先可以看到,最上面我定义了一些*Granted布尔型变量,*Storages数组,*Denyed整型值,*Granted标识相关权限是否已被授权,*Storages数组标识在进行动态权限申请时,有没有请求授予该权限,*Denyed表明当前权限有没有被用户拒绝。compareCount表示已经比较判断过的权限个数,needCompareCount表示总共需要判断的权限个数,最后在做权限判断时,会依据这两个值想不相等,来决定自定义弹窗弹出的时间。
然后是我们的自定义弹窗,他的相关代码为:
AlertDialog mPermissionDialog;public void showSystemPermissionsSettingDialog(String tips) { final String mPackName = mActivity.getPackageName(); if (mPermissionDialog == null) { mPermissionDialog = new AlertDialog.Builder(mActivity) .setMessage(tips).setCancelable(false) .setPositiveButton("设置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { cancelPermissionDialog(); Uri packageURI = Uri.parse("package:" + mPackName); Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI); mActivity.startActivity(intent); mActivity.finish(); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //关闭页面或者做其他操作 cancelPermissionDialog(); } }) .create(); } mPermissionDialog.show();}//关闭对话框private void cancelPermissionDialog() { if (mPermissionDialog != null) { mPermissionDialog.cancel(); mPermissionDialog = null; if(mActivity != null){ mActivity.finish(); } }}
如上表所示,如果我们点击了app界面的自定义弹窗的设置按钮,系统将会自动跳转到系统的应用的权限设置界面,他是通过打开Settings.ACTION_APPLICATION_DETAILS_SETTINGS的intent来实现跳转的。
好了,接下来我们再看MainActivity中的相关调用代码:
MyPermissionsUtil permissionsUtil;
@Overrideprotected void onCreate(Bundle savedInstanceState) {
//权限检查,只有android6.0及其以上才需要动态权限检查
permissionsUtil = new MyPermissionsUtil();
permissionsUtil.checkMorePermissions(this, MyPermissionsUtil.permissions_storage, MyPermissionsUtil.permissions_audio, MyPermissionsUtil.permissions_camera, MyPermissionsUtil.permissions_location, MyPermissionsUtil.permissions_phone, MyPermissionsUtil.permissions_calendar, MyPermissionsUtil.permissions_contacts, MyPermissionsUtil.permissions_sms, MyPermissionsUtil.permissions_sensors
}
如上表,首先定义咱们权限监测工具类的全局变量,然后在onCreate()方法里面对permissionsUtil 进行赋值,然后再调用权限监测工具类里面的监测多组权限的方法,第一个参数为this,即他自己当前acticity,剩余九个参数一定要按顺序填写,如果不需要申请某个权限组,则把他对应的设置成null就可以了。
接着将一下activity里面的回调函数checkPermissions(Activity activity, String[] needChecks, int requestCode),这个函数我们上边也有介绍,不管是申请单个权限还是多组权限,最后的结果都会经过这个回调函数,我们可以在里面自定义逻辑,他的代码为:
@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); boolean granted = false; switch (requestCode) { case MyPermissionsUtil.requestCode_storage: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_storage, grantResults); if (granted) { if (!permissions[0].contains("_EXTERNAL_STORAGE")) { granted = false; } } if (permissions != null && permissions.length > 0 && permissions[0].contains("_EXTERNAL_STORAGE")) { permissionsUtil.compareCount++; } permissionsUtil.storagesGranted = granted; if (!granted) { permissionsUtil.storagesDenyed++; System.out.println("权限不通过:" + requestCode); } else { permissionsUtil.storagesDenyed = 0; System.out.println("权限通过:" + requestCode); } break; case MyPermissionsUtil.requestCode_audio: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_audio, grantResults); System.out.println("我被执行了啊啊:" + granted + " , " + requestCode + " : " + permissions[0]); if (granted) { if (!permissions[0].contains("RECORD_AUDIO")) { granted = false; } } if (permissions != null && permissions.length > 0 && permissions[0].contains("RECORD_AUDIO")) { permissionsUtil.compareCount++; } permissionsUtil.audiosGranted = granted; if (!granted) { permissionsUtil.audiosDenyed++; System.out.println("权限不通过:" + requestCode); System.out.println("audioDenyed: " + permissionsUtil.audiosDenyed); } else { permissionsUtil.audiosDenyed = 0; System.out.println("权限通过:" + requestCode); } break; case MyPermissionsUtil.requestCode_camera: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_camera, grantResults); if (granted) { if (!permissions[0].contains("CAMERA")) { granted = false; } } if (permissions != null && permissions.length > 0 && permissions[0].contains("CAMERA")) { permissionsUtil.compareCount++; } permissionsUtil.camerasGranted = granted; if (!granted) { permissionsUtil.camerasDenyed++; System.out.println("权限不通过:" + requestCode); System.out.println("camerasDenyed: " + permissionsUtil.camerasDenyed); } else { permissionsUtil.camerasDenyed = 0; System.out.println("权限通过:" + requestCode); } break; case MyPermissionsUtil.requestCode_location: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_location, grantResults); if (granted) { if (!permissions[0].contains("_LOCATION") ) { granted = false; } } if (permissions != null && permissions.length > 0 && permissions[0].contains("_LOCATION")) { permissionsUtil.compareCount++; } permissionsUtil.locationsGranted = granted; if (!granted) { permissionsUtil.locationsDenyed++; System.out.println("权限不通过:" + requestCode); System.out.println("locationsDenyed: " + permissionsUtil.locationsDenyed); } else { permissionsUtil.locationsDenyed = 0; System.out.println("权限通过:" + requestCode); } break; case MyPermissionsUtil.requestCode_phone: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_phone, grantResults); if (granted) { if ((!permissions[0].contains("_PHONE") && !permissions[0].contains("_CALL"))) { granted = false; } } if (permissions != null && permissions.length > 0 && (permissions[0].contains("_PHONE") || permissions[0].contains("_CALL"))) { permissionsUtil.compareCount++; } permissionsUtil.phonesGranted = granted; if (!granted) { permissionsUtil.phonesDenyed++; System.out.println("权限不通过:" + requestCode); } else { permissionsUtil.phonesDenyed = 0; System.out.println("权限通过:" + requestCode); } break; case MyPermissionsUtil.requestCode_calendar: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_calendar, grantResults); if (granted) { if (!permissions[0].contains("_CALENDAR")) { granted = false; } } if (permissions != null && permissions.length > 0 && permissions[0].contains("_CALENDAR")) { permissionsUtil.compareCount++; } permissionsUtil.calendarsGranted = granted; if (!granted) { permissionsUtil.calendarsDenyed++; System.out.println("权限不通过:" + requestCode); } else { permissionsUtil.calendarsDenyed = 0; System.out.println("权限通过:" + requestCode); } break; case MyPermissionsUtil.requestCode_contacts: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_contacts, grantResults); if (granted) { if (!permissions[0].contains("_CONTACTS") && !permissions[0].contains("_ACCOUNTS")) { granted = false; } } if (permissions != null && permissions.length > 0 && (permissions[0].contains("_CONTACTS") || permissions[0].contains("_ACCOUNTS"))) { permissionsUtil.compareCount++; } permissionsUtil.contactsGranted = granted; if (!granted) { permissionsUtil.contactsDenyed++; System.out.println("权限不通过:" + requestCode); } else { permissionsUtil.contactsDenyed = 0; System.out.println("权限通过:" + requestCode); } break; case MyPermissionsUtil.requestCode_sms: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_sms, grantResults); if (granted) { if (!permissions[0].contains("_SMS") && !permissions[0].contains("_WAP_PUSH")) { granted = false; } } if (permissions != null && permissions.length > 0 && (permissions[0].contains("_SMS") || permissions[0].contains("_WAP_PUSH"))) { permissionsUtil.compareCount++; } permissionsUtil.smsGranted = granted; if (!granted) { permissionsUtil.smsDenyed++; System.out.println("权限不通过:" + requestCode); } else { permissionsUtil.smsDenyed = 0; System.out.println("权限通过:" + requestCode); } break; case MyPermissionsUtil.requestCode_sensors: granted = MyPermissionsUtil.getGranted(MyPermissionsUtil.permissions_sensors, grantResults); if (granted) { if (!permissions[0].contains("BODY_SENSORS")) { granted = false; } } if (permissions != null && permissions.length > 0 && permissions[0].contains("BODY_SENSORS")) { permissionsUtil.compareCount++; } permissionsUtil.sensorsGranted = granted; if (!granted) { permissionsUtil.sensorsDenyed++; System.out.println("权限不通过:" + requestCode); } else { permissionsUtil.sensorsDenyed = 0; System.out.println("权限通过:" + requestCode); } break; } System.out.println(requestCode + " : compareCount: " + MyPermissionsUtil.compareCount+ ",needCompareCount: " + MyPermissionsUtil.needCompareCount); if (!permissionsUtil.audiosGranted && permissionsUtil.checkAudios != null && permissionsUtil.audiosDenyed < 1) { System.out.println("audioDenyed我被执行力-----: " + permissionsUtil.audiosDenyed); ActivityCompat.requestPermissions(this, permissionsUtil.checkAudios, MyPermissionsUtil.requestCode_audio); } else if (!permissionsUtil.camerasGranted && permissionsUtil.checkCameras != null && permissionsUtil.camerasDenyed < 1) { System.out.println("camerasDenyed: " + permissionsUtil.camerasDenyed); ActivityCompat.requestPermissions(this, permissionsUtil.checkCameras, MyPermissionsUtil.requestCode_camera); } else if (!permissionsUtil.locationsGranted && permissionsUtil.checkLocations != null && permissionsUtil.locationsDenyed < 1) { System.out.println("locationsDenyed: " + permissionsUtil.locationsDenyed); ActivityCompat.requestPermissions(this, permissionsUtil.checkLocations, MyPermissionsUtil.requestCode_location); } else if (!permissionsUtil.phonesGranted && permissionsUtil.checkPhones != null && permissionsUtil.phonesDenyed < 1) { ActivityCompat.requestPermissions(this, permissionsUtil.checkPhones, MyPermissionsUtil.requestCode_phone); } else if (!permissionsUtil.calendarsGranted && permissionsUtil.checkCalendars != null && permissionsUtil.calendarsDenyed < 1) { ActivityCompat.requestPermissions(this, permissionsUtil.checkCalendars, MyPermissionsUtil.requestCode_calendar); } else if (!permissionsUtil.contactsGranted && permissionsUtil.checkContacts != null && permissionsUtil.contactsDenyed < 1) { ActivityCompat.requestPermissions(this, permissionsUtil.checkContacts, MyPermissionsUtil.requestCode_contacts); } else if (!permissionsUtil.smsGranted && permissionsUtil.checkSms != null && permissionsUtil.smsDenyed < 1) { ActivityCompat.requestPermissions(this, permissionsUtil.checkSms, MyPermissionsUtil.requestCode_sms); } else if (!permissionsUtil.sensorsGranted && permissionsUtil.checkSensors != null && permissionsUtil.sensorsDenyed < 1) { ActivityCompat.requestPermissions(this, permissionsUtil.checkSensors, MyPermissionsUtil.requestCode_sensors); } //所有权限都判断完之后,再判断下有哪些关键权限,必须要授权的,却没有授权,提示用户,必须打开权限 if ((MyPermissionsUtil.compareCount== MyPermissionsUtil.needCompareCount) && MyPermissionsUtil.mustGrantedPermiss!= null && MyPermissionsUtil.mustGrantedPermiss.length > 0) { boolean needTip_storage = false; boolean needTip_audio = false; boolean needTip_camera = false; boolean needTip_location = false; boolean needTip_phone = false; boolean needTip_calendar = false; boolean needTip_contact = false; boolean needTip_sms = false; boolean needTip_sensor = false; for (int i = 0; i < MyPermissionsUtil.mustGrantedPermiss.length; i++) { String permission = MyPermissionsUtil.mustGrantedPermiss[i]; if (permission.contains("_EXTERNAL_STORAGE") && !permissionsUtil.storagesGranted && checkSelfPermission(permission) != MyPermissionsUtil.granted) { needTip_storage = true; } if (permission.contains("RECORD_AUDIO") && !permissionsUtil.audiosGranted && checkSelfPermission(permission) != MyPermissionsUtil.granted) { needTip_audio = true; } if (permission.contains("CAMERA") && !permissionsUtil.camerasGranted && checkSelfPermission(permission) != MyPermissionsUtil.granted) { needTip_camera = true; } if (permission.contains("_LOCATION") && !permissionsUtil.locationsGranted ) { needTip_location = true; for(int j = 0; j < MyPermissionsUtil.permissions_location.length;j++){ if(checkSelfPermission(MyPermissionsUtil.permissions_location[j]) == MyPermissionsUtil.granted){ needTip_location = false; break; } } } if ((permission.contains("_PHONE") || permission.contains("_CALL")) && !permissionsUtil.phonesGranted && checkSelfPermission(permission) != MyPermissionsUtil.granted) { needTip_phone = true; } if (permission.contains("_CALENDAR") && !permissionsUtil.calendarsGranted && checkSelfPermission(permission) != MyPermissionsUtil.granted) { needTip_calendar = true; } if ((permission.contains("_CONTACTS") || permission.contains("_ACCOUNTS")) && !permissionsUtil.contactsGranted && checkSelfPermission(permission) != MyPermissionsUtil.granted) { needTip_contact = true; } if ((permission.contains("_SMS") || permission.contains("_WAP_PUSH")) && !permissionsUtil.smsGranted && checkSelfPermission(permission) != MyPermissionsUtil.granted) { needTip_sms = true; } if (permission.contains("BODY_SENSORS") && !permissionsUtil.sensorsGranted && checkSelfPermission(permission) != MyPermissionsUtil.granted) { needTip_sensor = true; } } System.out.println("needTips: " + needTip_storage + "," + needTip_audio + "," + needTip_camera + "," + needTip_location + "," + needTip_phone + "," + needTip_calendar + "," + needTip_contact + "," + needTip_sms + "," + needTip_sensor); StringBuffer sb = new StringBuffer(); if (needTip_storage) {//本App用到权限,非常重要,为保证app能够正常使用,请在应用程序权限设置界面,授予该权限 sb.append("STORAGE存储卡文件读写权限、"); } if (needTip_audio) { sb.append("MICROPHONE麦克风录音权限、"); } if (needTip_camera) { sb.append("CAMERA相机权限、"); } if (needTip_location) { sb.append("LOCATION位置权限、"); } if (needTip_phone) { sb.append("PHONE手机权限、"); } if (needTip_calendar) { sb.append("CALENDAR日历权限、"); } if (needTip_contact) { sb.append("CONTACTS联系人权限、"); } if (needTip_sms) { sb.append("SMS短信权限、"); } if (needTip_sensor) { sb.append("BODY_SENSORS传感器权限、"); } if (sb != null && sb.length() > 0) { String tips = sb.toString(); tips = tips.substring(0, tips.length() - 1); tips = "已禁用 " + tips + ",为保证本App相关功能都能够正常执行,保证程序正常运行,请在系统的应用的权限设置界面上勾选相应权限!"; permissionsUtil.showSystemPermissionsSettingDialog(tips); } }}
除了上面的那些之外,还需要注意,动态申请的权限也需要在AndroidManifest.xml文件中声明,该事例应用中的所有动态权限如下,你可以安装你自己app的需要选用: