一、申请权限
申请权限 步骤 :
权限判定 : 首先要判定是否已经授权指定的权限数组 ; 调用 EasyPermissions.hasPermissions 方法 , 进行判定 ;
/** * 检查当前的上下文对象 ( 应用 ) 是否被授权指定的权限集合 * * @param context 调用方法的上下文对象. * @param perms 一个或多个权限, 如 {@link Manifest.permission#CAMERA}. * @return true 如果所有的权限都被授权了返回 true, 如果有一个权限没有被授予就会返回 false * yet granted. * @see Manifest.permission */ public static boolean hasPermissions(@NonNull Context context, @Size(min = 1) @NonNull String... perms)
权限判定分支 : 如果有要求的权限 , 就开始执行实际的逻辑 , 如果没有权限 , 就需要申请权限 ;
申请权限 : 调用 EasyPermissions.requestPermissions 方法 , 申请权限 ;
/** * 申请一组权限, 如果系统要求 ( 用户之前拒绝过 ) , 显示 权限申请原理对话框 , * 向用户表明申请该权限的原因 . * * @param host 上下文对象 , 一般是 Activity. * @param rationale 解释为什么申请改组权限的原因的信息; * 这些信息会在用户第一次拒绝权限申请后显示在 权限申请原理对话框 中. * @param requestCode 追踪本次权限申请的申请码 , 必须小于 256. * @param perms 本次申请的权限 , 这是一个可变参数 . * @see Manifest.permission */ public static void requestPermissions( @NonNull Activity host, @NonNull String rationale, int requestCode, @Size(min = 1) @NonNull String... perms) { requestPermissions( new PermissionRequest.Builder(host, requestCode, perms) .setRationale(rationale) .build()); }
注解中使用的常量定义 : 如果要在 @AfterPermissionGranted() 注解中使用常量 , 该常量只能使用 const val 定义 ;
定义方式 : const val 常量才是 Java 中的 public static final 对等的常量值 ; 定义位置 : const val 常量只能定义在 Kotlin 文件顶层, 或 object 对象表达式中, 不能定义在类中 ; /** * 权限申请码, 作为权限申请的标识 * 注意 : const val 常量才是 Java 中的 public static final 对等的常量值 * const val 常量只能定义在 Kotlin 文件中, 或 object 对象表达式中, 不能定义在类中 */ const val PERMISSION_REQUEST_CODE : Int = 100;
数组转为可变参数 : Kotlin 中可以使用 Array<String> 数组作为可变参数 , 数组前加上 * 符号 , 可以将数组展开 , 转为可变数组 , 如 *PERMMISSIONS ;
/** * 当做可变参数时 , 前面加上 * 符号 , 展开数组 * *PERMMISSIONS 等同于可变参数 */ var PERMMISSIONS: Array<String> = arrayOf(Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS, Manifest.permission.READ_SMS, Manifest.permission.WRITE_EXTERNAL_STORAGE)
申请权限代码示例 :
/** * AfterPermissionGranted 注解的作用是 , 当 请求吗 666 对应的权限申请全部通过后 * 再次回调一次该方法 . ( 相当于调用了两次该方法 ) */ @AfterPermissionGranted( PERMISSION_REQUEST_CODE ) fun doSomethingWithPermissions(){ Log.i(TAG, "doSomethingWithPermissions") // 数组前加上 * 符号 , 可以将数组展开 , 转为可变数组 // 调用 EasyPermissions.hasPermissions 方法判定是否已经申请该权限 if(EasyPermissions.hasPermissions(this, *PERMMISSIONS)){ // 如果有上述权限, 执行该操作 Toast.makeText(this, "权限申请通过", Toast.LENGTH_LONG).show() }else{ // 如果没有上述权限 , 那么申请权限 EasyPermissions.requestPermissions( this, "权限申请原理对话框 : 描述申请权限的原理", PERMISSION_REQUEST_CODE, // 数组前加上 * 符号 , 可以将数组展开 , 转为可变数组 *PERMMISSIONS ) } }
申请权限结果响应操作 : 重写 Activity 的 onRequestPermissionsResult 方法 , 申请权限完成后 , 不管成功还是失败 , 都会回调 该方法 , 在此处将后续操作全部交给 EasyPermissions 操作 ;
/** * 二 、 重写 Activity 的 onRequestPermissionsResult 方法 * 主要是在该方法中使用 EasyPermissions 进一步处理权限申请后续结果 */ override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray){ super.onRequestPermissionsResult(requestCode, permissions, grantResults) Log.i(TAG, "onRequestPermissionsResult") // 进一步使用 EasyPermissions 处理后续结果 EasyPermissions.onRequestPermissionsResult( requestCode, permissions, grantResults, this); }
调用 EasyPermissions.onRequestPermissionsResult 的结果就是 , 如果用户同意了权限申请 , 就会回调 onPermissionsGranted 方法 , 如果用户拒绝了权限申请 , 就会回调 onPermissionsDenied 方法 ;
二、申请权限原理对话框
如果选择了 “拒绝” 选项 , 那就摊上事了 , 后面连带一大堆操作 , 处理后续权限管理的问题 ;
之前用户选择了拒绝 , 再次申请 , 就会自动弹出 权限申请原理对话框 , 该对话框的主要作用是 描述 申请权限的原理 ;
如果第一次申请权限 , 拒绝了某些权限的申请 , 第二次就会自动弹出 申请权限原理对话框 , 在这个对话框中 , 开发者需要给出为什么申请这些权限 , 说服用户同意这些权限的申请 ;
申请权限原理对话框 中的内容是在 EasyPermissions.requestPermissions 方法的参数中设定的 ;
回调函数 : 在 Activity 中实现 EasyPermissions.RationaleCallbacks 接口 , 在本 Activity 中调用 EasyPermissions.requestPermissions 方法申请权限时 , 就会自动应用上述机制 ,
/** * 申请权限原理对话框操作对应的回调函数 */ public interface RationaleCallbacks { void onRationaleAccepted(int requestCode); void onRationaleDenied(int requestCode); }
申请权限原理对话框 : 用户申请权限 , 如果是首次申请 , 该对话框不弹出 , 如果不是首次申请 , 并且之前拒绝过某些权限申请 , 就会弹出该对话框 , 用户进行以下操作 :
用户点击 确定 : 就会继续执行权限申请的流程 , 弹出 权限申请 弹窗 ; 回调 onRationaleAccepted 方法 ;
用户点击 取消 : 一般不做任何操作 ; 回调 onRationaleDenied 方法 ;
代码示例 :
/** * 申请权限原理对话框操作对应的回调函数 */ public interface RationaleCallbacks { void onRationaleAccepted(int requestCode); void onRationaleDenied(int requestCode); }