运行时权限简易工具类 /** * Created by ccMagic on 2017/8/31 21:42 * 运行时权限工具类 * 1、在运行时权限的对话框弹出时,activity是处于onPause状态 * 2、当需要的危险权限没有在AndroidManifest中声明
/** * Created by ccMagic on 2017/8/31 21:42 * 运行时权限工具类 * 1、在运行时权限的对话框弹出时,activity是处于onPause状态 * 2、当需要的危险权限没有在AndroidManifest中声明的时候,运行时权限不会有作用,并且默认直接调用到onRequestPermissionsResult方法中,结果是拒绝的 * 3、申请通过了一个权限,则这个权限所在权限组里的所有权限都申请通过 */ public class RunningTimePermissionUtil { private static final String TAG = "RunningTimePermissionUt"; private static final int permissionCode = 110; //日历数据 // permission group : CALENDAR // permission 1 : READ_CALENDAR // permission 2 : WRITE_CALENDAR public static final int CALENDAR = 1; //相机 //permission group : CAMERA //permission 1 : CAMERA public static final int CAMERA = 2; //联系人 //permission group : CONTACTS //permission 1 : READ_CONTACTS //permission 2 : WRITE_CONTACTS //permission 3 : GET_ACCOUNTS public static final int CONTACTS = 3; //位置 //permission group : LOCATION //permission 1 : ACCESS_FINE_LOCATION //permission 2 : ACCESS_COARSE_LOCATION public static final int LOCATION = 4; //麦克风 //permission group : MICROPHONE //permission 1 : RECORD_AUDIO public static final int MICROPHONE = 5; //电话 //permission group : PHONE //permission 1 : READ_PHONE_STATE //permission 2 : CALL_PHONE //permission 3 : READ_CALL_LOG //permission 4 : WRITE_CALL_LOG //permission 5 : ADD_VOICEMAIL //permission 6 : USE_SIP //permission 7 : PROCESS_OUTGOING_CALLS public static final int PHONE = 6; //传感器 //permission group : SENSORS //permission 1 : BODY_SENSORS public static final int SENSORS = 7; //短信 //permission group : SMS //permission 1 : SEND_SMS //permission 2 : RECEIVE_SMS //permission 3 : READ_SMS //permission 4 : RECEIVE_WAP_PUSH //permission 5 : RECEIVE_MMS public static final int SMS = 8; //存储 //permission group : STORAGE //permission 1 : READ_EXTERNAL_STORAGE //permission 2 : WRITE_EXTERNAL_STORAGE public static final int STORAGE = 9; private static RunningTimePermissionInterface runningTimePermissionInterfaceThis; @IntDef({CALENDAR, CAMERA, CONTACTS, LOCATION, MICROPHONE, PHONE, SENSORS, SMS, STORAGE}) @Retention(RetentionPolicy.SOURCE) private @interface PermissionCode { } /** * 授权结果处理接口 */ public interface RunningTimePermissionInterface { /** * 授权成功 * * @param grantedPermissions 已经授权的权限 */ void permissionGranted(Liststrings.xmlgrantedPermissions); /** * 拒绝/授权失败 * * @param deniedPermissions 已经拒绝的权限 */ void permissionDenied(List deniedPermissions); } /** * 授权处理过程 * * @param fragment Fragment * @param permissionCodes 授权码数组 * @param runningTimePermissionInterface 授权结果处理接口 **/ public static void runningTimePermission(@NonNull BaseFragment fragment, @PermissionCode int[] permissionCodes, RunningTimePermissionInterface runningTimePermissionInterface) { if (Build.VERSION.SDK_INT >= 23) { runningTimePermissionInterfaceThis = runningTimePermissionInterface; //选择权限类型 //申请通过了一个权限,则这个权限组里的所有权限都申请通过 List permissions = new ArrayList<>(); for (int permissionCode : permissionCodes) { switch (permissionCode) { case CALENDAR: permissions.add(Manifest.permission.READ_CALENDAR); permissions.add(Manifest.permission.WRITE_CALENDAR); break; case CAMERA: permissions.add(Manifest.permission.CAMERA); break; case LOCATION: permissions.add(Manifest.permission.ACCESS_FINE_LOCATION); permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); break; case CONTACTS: permissions.add(Manifest.permission.READ_CONTACTS); permissions.add(Manifest.permission.WRITE_CONTACTS); permissions.add(Manifest.permission.GET_ACCOUNTS); break; case MICROPHONE: permissions.add(Manifest.permission.RECORD_AUDIO); break; case PHONE: permissions.add(Manifest.permission.READ_PHONE_STATE); permissions.add(Manifest.permission.CALL_PHONE); permissions.add(Manifest.permission.READ_CALL_LOG); permissions.add(Manifest.permission.WRITE_CALL_LOG); permissions.add(Manifest.permission.ADD_VOICEMAIL); permissions.add(Manifest.permission.USE_SIP); permissions.add(Manifest.permission.PROCESS_OUTGOING_CALLS); break; case SENSORS: permissions.add(Manifest.permission.BODY_SENSORS);//android m 才有运行时权限机制,所以API level 必定大于23 break; case SMS: permissions.add(Manifest.permission.SEND_SMS); permissions.add(Manifest.permission.RECEIVE_SMS); permissions.add(Manifest.permission.READ_SMS); permissions.add(Manifest.permission.RECEIVE_WAP_PUSH); permissions.add(Manifest.permission.RECEIVE_MMS); break; case STORAGE: permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); break; default: ActivityUtils.toast(fragment.getActivity(), fragment.getString(R.string.request_code_error)); return; } } List noPermissions = new ArrayList<>();//记录未获得权限 List permissionSign = new ArrayList<>();//已获取的 //进行权限检测 for (String permission : permissions) { if (ContextCompat.checkSelfPermission(fragment.getActivity(), permission) == PackageManager.PERMISSION_DENIED) { //没有获取的权限记录下来 noPermissions.add(permission); } else { Integer integer = switchPermissionToConstant(permission); boolean have = false; for (Integer integer1 : permissionSign) {//避免添加重复内容 if (integer.equals(integer1)) { have = true; break; } } if (!have) { permissionSign.add(integer); } } } //重新申请没有获取的权限 String[] noPermissionsArray = new String[noPermissions.size()]; for (int i = 0, size = noPermissionsArray.length; i < size; i++) { noPermissionsArray[i] = noPermissions.get(i); } if (noPermissionsArray.length > 0) { // 还没有授权,就开始授权 // 第一个参数是String数组,把要申请的权限名放在数组中 // 第二个参数是请求码,只要是唯一值就可以了. fragment.requestPermissions(noPermissionsArray, permissionCode); //调用了requestPermissions后,系统会弹出一个权限申请对话框 //然后用户选择同意或拒绝权限申请 //不论哪种结果,最终都会回调到onRequestPermissionResult()方法中 //而授权的结果则会封装在grantResults参数中 } else { runningTimePermissionInterfaceThis.permissionGranted(permissionSign); } } } /** * 授权处理过程 * * @param activity 授权处理的活动对象 * @param permissionCodes 授权码数组 * @param runningTimePermissionInterface 授权结果处理接口 **/ public static void runningTimePermission(@NonNull Activity activity, @PermissionCode int[] permissionCodes, RunningTimePermissionInterface runningTimePermissionInterface) { runningTimePermissionInterfaceThis = runningTimePermissionInterface; //选择权限类型 //申请通过了一个权限,则这个权限组里的所有权限都申请通过 List permissions = new ArrayList<>(); for (int permissionCode : permissionCodes) { switch (permissionCode) { case CALENDAR: permissions.add(Manifest.permission.READ_CALENDAR); permissions.add(Manifest.permission.WRITE_CALENDAR); break; case CAMERA: permissions.add(Manifest.permission.CAMERA); break; case LOCATION: permissions.add(Manifest.permission.ACCESS_FINE_LOCATION); permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); break; case CONTACTS: permissions.add(Manifest.permission.READ_CONTACTS); permissions.add(Manifest.permission.WRITE_CONTACTS); permissions.add(Manifest.permission.GET_ACCOUNTS); break; case MICROPHONE: permissions.add(Manifest.permission.RECORD_AUDIO); break; case PHONE: permissions.add(Manifest.permission.READ_PHONE_STATE); permissions.add(Manifest.permission.CALL_PHONE); permissions.add(Manifest.permission.READ_CALL_LOG); permissions.add(Manifest.permission.WRITE_CALL_LOG); permissions.add(Manifest.permission.ADD_VOICEMAIL); permissions.add(Manifest.permission.USE_SIP); permissions.add(Manifest.permission.PROCESS_OUTGOING_CALLS); break; case SENSORS: permissions.add(Manifest.permission.BODY_SENSORS);//android m 才有运行时权限机制,所以API level 必定大于23 break; case SMS: permissions.add(Manifest.permission.SEND_SMS); permissions.add(Manifest.permission.RECEIVE_SMS); permissions.add(Manifest.permission.READ_SMS); permissions.add(Manifest.permission.RECEIVE_WAP_PUSH); permissions.add(Manifest.permission.RECEIVE_MMS); break; case STORAGE: permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); break; default: ActivityUtils.toast(activity, activity.getString(R.string.request_code_error)); return; } } List noPermissions = new ArrayList<>();//记录未获得权限 List permissionSign = new ArrayList<>();//已获取的 //进行权限检测 for (String permission : permissions) { if (ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_DENIED) { //没有获取的权限记录下来 noPermissions.add(permission); } else { Integer integer = switchPermissionToConstant(permission); boolean have = false; for (Integer integer1 : permissionSign) {//避免添加重复内容 if (integer.equals(integer1)) { have = true; break; } } if (!have) { permissionSign.add(integer); } } } //重新申请没有获取的权限 String[] noPermissionsArray = new String[noPermissions.size()]; for (int i = 0, size = noPermissionsArray.length; i < size; i++) { noPermissionsArray[i] = noPermissions.get(i); } if (noPermissionsArray.length > 0) { // 还没有授权,就开始授权 // 第一个参数是Activity实例 // 第二个参数是String数组,把要申请的权限名放在数组中 // 第三个参数是请求码,只要是唯一值就可以了 requestPermissions(activity, noPermissionsArray, permissionCode); //调用了requestPermissions后,系统会弹出一个权限申请对话框 //然后用户选择同意或拒绝权限申请 //不论哪种结果,最终都会回调到onRequestPermissionResult()方法中 //而授权的结果则会封装在grantResults参数中 } else { runningTimePermissionInterfaceThis.permissionGranted(permissionSign); } } /** * 授权处理过程 用于处理onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)的回调结果 * * @param activity Activity * @param requestCode 授权码 * @param permissions 请求的权限 * @param grantResults 请求结果,length与permissions的相同,一一对应permissions中权限的状态(允许/拒绝) **/ public static void onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions, int[] grantResults) { Log.i(TAG, "onRequestPermissionsResult"); if (permissionCode == requestCode) { if (permissions == null || grantResults == null) { ActivityUtils.toast(activity, activity.getString(R.string.request_permissions_result_error)); return; } Log.i(TAG, "List granted = new ArrayList<>()"); List granted = new ArrayList<>(); List denied = new ArrayList<>(); for (int i = 0, size = permissions.length; i < size; i++) { if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { //允许了的权限 Integer integer = switchPermissionToConstant(permissions[i]); boolean have = false; for (Integer integer1 : granted) {//避免添加重复内容 if (integer.equals(integer1)) { have = true; break; } } if (!have) { granted.add(integer); } } else if (grantResults[i] == PackageManager.PERMISSION_DENIED) { //拒绝了的权限 Integer integer = switchPermissionToConstant(permissions[i]); boolean have = false; for (Integer integer1 : denied) {//避免添加重复内容 if (integer.equals(integer1)) { have = true; break; } } if (!have) denied.add(integer); } } //如果需要显示拒绝的权限内容,则可调用此方法显示出来 showDeniedPermission(activity, denied); //授权结果 if (runningTimePermissionInterfaceThis != null) { runningTimePermissionInterfaceThis.permissionGranted(granted); runningTimePermissionInterfaceThis.permissionDenied(denied); } } } /** * 显示被拒绝的权限内容 * * @param activity Activity * @param denied 被拒绝的权限list */ private static void showDeniedPermission(Activity activity, List denied) { Log.i("Permissions", "showDeniedPermission"); //由于申请通过了一个权限,则这个权限组里的所有权限都申请通过 //记录决绝的权限提示信息 StringBuilder stringBuilder = new StringBuilder(); //布尔变量标识请求的权限组的,个数检测标记出来的是否被拒绝了 for (Integer deniedPermission : denied) { switch (deniedPermission) { case CALENDAR: stringBuilder.append(activity.getString(R.string.denied_calendar_permission)); stringBuilder.append("\n"); break; case CAMERA: stringBuilder.append(activity.getString(R.string.denied_camera_permission)); stringBuilder.append("\n"); break; case CONTACTS: stringBuilder.append(activity.getString(R.string.denied_contacts_permission)); stringBuilder.append("\n"); break; case LOCATION: stringBuilder.append(activity.getString(R.string.denied_location_permission)); stringBuilder.append("\n"); break; case PHONE: stringBuilder.append(activity.getString(R.string.denied_phone_permission)); stringBuilder.append("\n"); break; case MICROPHONE: stringBuilder.append(activity.getString(R.string.denied_microphone_permission)); stringBuilder.append("\n"); break; case SENSORS: stringBuilder.append(activity.getString(R.string.denied_sensors_permission)); stringBuilder.append("\n"); break; case SMS: stringBuilder.append(activity.getString(R.string.denied_sms_permission)); stringBuilder.append("\n"); break; case STORAGE: stringBuilder.append(activity.getString(R.string.denied_storage_permission)); stringBuilder.append("\n"); break; } } String message = stringBuilder.toString(); if (!TextUtils.isEmpty(message)) { ActivityUtils.toast(activity, message.substring(0, message.length() - 1)); } } /** * 权限转换为对应的常量 */ private static int switchPermissionToConstant(String permission) { switch (permission) { case Manifest.permission.READ_CALENDAR: return CALENDAR; case Manifest.permission.WRITE_CALENDAR: return CALENDAR; case Manifest.permission.CAMERA: return CAMERA; case Manifest.permission.ACCESS_FINE_LOCATION: return LOCATION; case Manifest.permission.ACCESS_COARSE_LOCATION: return LOCATION; case Manifest.permission.READ_CONTACTS: return CONTACTS; case Manifest.permission.WRITE_CONTACTS: return CONTACTS; case Manifest.permission.GET_ACCOUNTS: return CONTACTS; case Manifest.permission.RECORD_AUDIO: return MICROPHONE; case Manifest.permission.READ_PHONE_STATE: return PHONE; case Manifest.permission.CALL_PHONE: return PHONE; case Manifest.permission.READ_CALL_LOG: return PHONE; case Manifest.permission.WRITE_CALL_LOG: return PHONE; case Manifest.permission.ADD_VOICEMAIL: return PHONE; case Manifest.permission.USE_SIP: return PHONE; case Manifest.permission.PROCESS_OUTGOING_CALLS: return PHONE; case Manifest.permission.BODY_SENSORS://android m 才有运行时权限机制,所以API level 必定大于23 return SENSORS; case Manifest.permission.SEND_SMS: return SMS; case Manifest.permission.RECEIVE_SMS: return SMS; case Manifest.permission.READ_SMS: return SMS; case Manifest.permission.RECEIVE_WAP_PUSH: return SMS; case Manifest.permission.RECEIVE_MMS: return SMS; case Manifest.permission.READ_EXTERNAL_STORAGE: return STORAGE; case Manifest.permission.WRITE_EXTERNAL_STORAGE: return STORAGE; } return -1; } }
您拒绝了日历服务权限 您拒绝了相机服务权限 您拒绝了联系人服务权限 您拒绝了位置服务权限 您拒绝了麦克风服务权限 您拒绝了电话服务权限 您拒绝了传感器服务权限 您拒绝了短信服务权限 您拒绝了存储服务权限 权限码出错:没有填写正确的权限码 运行时权限处理回调出错