三、引导用户手动设置权限对话框
如果用户在 授权界面 选择了 “拒绝, 不要再询问” , 这事比上面的还要大 , 此时权限对话框根本就无法弹出 , 只能到设置界面取设置权限 ;
引导用户手动设置权限对话框 : 该对话框的作用就是 引导用户跳转到设置界面 , 设置需要的权限 ;
这个对话框需要自定义 , 但是 EasyPermission 库给提供了一个 AppSettingsDialog 对话框 , 其作用就是引导用户跳转到设置界面 , 设置对话框 ;
判定是否存在永久拒绝的权限 : 调用 EasyPermissions.somePermissionPermanentlyDenied 方法 , 判定是否存在被永久拒绝的权限 , 如果有 , 那么 创建 AppSettingsDialog 对话框 ,
弹出 引导用户手动设置权限对话框 代码示例 :
// 如果申请的权限中有任何一个权限存在 永久拒绝 的情况 if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { // 设置 引导用户前往设置界面 自行设置权限的引导对话框 AppSettingsDialog.Builder(this) .setTitle("需要手动设置权限") .setRationale("存在永久拒绝的权限 , 需要手动前往设置界面为应用进行授权") .setPositiveButton("前往设置界面") .setNegativeButton("不使用该功能") .build().show() }
弹出的对话框样式 :
如果点击 “前往设置界面” , 就会跳转到 应用信息 设置界面 :
操作完毕返回操作 : 从该对话框返回 , 不管是点击哪个按钮 , 都会进入该方法中 , 此时判定是否授权成功 , 如果没有授权成功 , 给用户进行提示 ; 如果有授权成功 , 那么进行后续操作 ;
/** * 从 AppSettingsDialog 界面中返回, 回调该方法 */ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE){ // 判断五种权限是否申请成功 var hasPermissions = EasyPermissions.hasPermissions(this, *PERMMISSIONS) // 界面中显示权限申请结果 Toast.makeText(this, "设置界面用户手动申请权限结果 $hasPermissions", Toast.LENGTH_LONG).show() } }
四、在 AndroidManifest.xml 中配置权限
一定不要忘记在 AndroidManifest.xml 中配置权限 , 否则无法使用 ;
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="kim.hsl.easypermissions"> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
五、完整代码示例
package kim.hsl.easypermissions import android.Manifest import android.content.Intent import android.os.Bundle import android.util.Log import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import pub.devrel.easypermissions.AfterPermissionGranted import pub.devrel.easypermissions.AppSettingsDialog import pub.devrel.easypermissions.EasyPermissions import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks import pub.devrel.easypermissions.EasyPermissions.RationaleCallbacks /** * 权限申请码, 作为权限申请的标识 * 注意 : const val 常量才是 Java 中的 public static final 对等的常量值 * const val 常量只能定义在 Kotlin 文件中, 或 object 对象表达式中, 不能定义在类中 */ const val PERMISSION_REQUEST_CODE : Int = 100; class MainActivity : AppCompatActivity(), PermissionCallbacks, RationaleCallbacks{ val TAG = "MainActivity" /** * 当做可变参数时 , 前面加上 * 符号 , 展开数组 * *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) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } /* 一 、 用户点击按钮开始申请权限 */ fun onCLick(view : View){ // 申请权限, 并在权限申请通过后 , 在执行一次该方法 doSomethingWithPermissions(); } /** * 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 进一步处理权限申请后续结果 */ 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.PermissionCallbacks 接口中的方法 */ /** * EasyPermissions.PermissionCallbacks 接口中实现的方法 * 调用 EasyPermissions.requestPermissions() 方法申请权限 , 用户点击拒绝授权后会回调该方法 */ override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { Log.i(TAG, "onPermissionsDenied 用户拒绝权限申请 , 请求码 $requestCode , 拒绝的权限 : $perms") // 如果申请的权限中有任何一个权限存在 永久拒绝 的情况 if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { // 设置 引导用户前往设置界面 自行设置权限的引导对话框 AppSettingsDialog.Builder(this) .setTitle("需要手动设置权限") .setRationale("存在永久拒绝的权限 , 需要手动前往设置界面为应用进行授权") .setPositiveButton("前往设置界面") .setNegativeButton("不使用该功能") .build().show() } } /** * EasyPermissions.PermissionCallbacks 接口中实现的方法 * 调用 EasyPermissions.requestPermissions() 方法申请权限 , 用户点击同意授权后会回调该方法 */ override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) { Log.i(TAG, "onPermissionsGranted 用户同意权限申请 , 请求码 $requestCode , 拒绝的权限 : $perms") } /* 四 、 实现 EasyPermissions.RationaleCallbacks 接口中的方法 */ /** * EasyPermissions.RationaleCallbacks 接口中的方法 * */ override fun onRationaleDenied(requestCode: Int) { Log.i(TAG, "权限申请原理对话框中选择 取消 , 请求码 $requestCode") } /** * EasyPermissions.RationaleCallbacks 接口中的方法 * */ override fun onRationaleAccepted(requestCode: Int) { Log.i(TAG, "权限申请原理对话框中选择 确定 , 请求码 $requestCode") } /* 五 、实现从 AppSettingsDialog 对话框返回的逻辑 主要是检查用户永久拒绝后, 查看引导用户设置权限的结果 */ /** * 从 AppSettingsDialog 界面中返回, 回调该方法 */ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE){ // 判断五种权限是否申请成功 var hasPermissions = EasyPermissions.hasPermissions(this, *PERMMISSIONS) // 界面中显示权限申请结果 Toast.makeText(this, "设置界面用户手动申请权限结果 $hasPermissions", Toast.LENGTH_LONG).show() } } }
六、GitHub 地址
https://github.com/han1202012/EasyPermissions