基于 permissionsdispatcher 库,创建的 BasePermissionsActivity 基类。

背景:permissionsdispatcher通过注解的使用方式处理权限申请,在单个页面的时候比较方便。
但是当需要进行权限申请的页面比较多是的时候,每个页面都需要重复相同的代码逻辑。

优点:

  • 直接继承 BasePermissionsActivity
  • 申请默认权限
  • 申请指定权限
  • 重写权限申请成功和失败回调
  • 可重写 onShowRationale() 对用户首次拒绝的权限进行说明

permissionsdispatcher 依赖

  1. dependencies {
  2. ......
  3. // 运行时权限
  4. implementation ("com.github.hotchemi:permissionsdispatcher:3.3.1"){
  5. exclude module: "support-v13"
  6. }
  7. }

BasePermissionsActivity 代码

  1. import android.Manifest
  2. import android.support.v7.app.AppCompatActivity
  3. import android.support.v4.app.ActivityCompat
  4. import permissions.dispatcher.*
  5. import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
  6. import android.content.Intent
  7. import android.net.Uri
  8. import android.support.v7.app.AlertDialog
  9. /**
  10. * @author ypw
  11. * @date 2019-08-29
  12. * @version 1.11.0
  13. * @des 动态权限检查基类
  14. */
  15. abstract class BasePermissionsActivity : AppCompatActivity() {
  16. /**
  17. * @author ypw
  18. * @date 2019-08-29
  19. * @version 1.11.0
  20. * @des 默认申请权限
  21. */
  22. val needsPermission = arrayOf(
  23. Manifest.permission.READ_PHONE_STATE,
  24. Manifest.permission.READ_EXTERNAL_STORAGE,
  25. Manifest.permission.WRITE_EXTERNAL_STORAGE
  26. )
  27. private val requestCode: Int = 0
  28. /**
  29. * @author ypw
  30. * @date 2019-08-29
  31. * @version 1.11.0
  32. * @des 请求默认权限
  33. */
  34. fun onRequestPermission() {
  35. onRequestPermission(needsPermission)
  36. }
  37. /**
  38. * @author ypw
  39. * @date 2019-08-29
  40. * @version 1.11.0
  41. * @des 请求指定权限
  42. */
  43. fun onRequestPermission(permissions: Array<String>) {
  44. if (PermissionUtils.hasSelfPermissions(this, *permissions)) {
  45. onPermissionSuccess()
  46. } else {
  47. if (PermissionUtils.shouldShowRequestPermissionRationale(this, *permissions)) {
  48. onShowRationale(permissions)
  49. } else {
  50. ActivityCompat.requestPermissions(this, permissions, requestCode)
  51. }
  52. }
  53. }
  54. /**
  55. * @author ypw
  56. * @date 2019-08-29
  57. * @version 1.11.0
  58. * @des 权限请求成功后调用
  59. */
  60. abstract fun onPermissionSuccess()
  61. /**
  62. * @author ypw
  63. * @date 2019-08-29
  64. * @version 1.11.0
  65. * @des 权限请求失败后调用
  66. */
  67. abstract fun onPermissionDenied()
  68. /**
  69. * @author ypw
  70. * @date 2019-08-29
  71. * @version 1.11.0
  72. * @des 首次权限请求拒绝后,再次权限请求时调用。可向用户进行权限说明
  73. */
  74. open fun onShowRationale(permissions: Array<String>) {
  75. showRationaleDialog {
  76. ActivityCompat.requestPermissions(this, permissions, requestCode)
  77. }
  78. }
  79. /**
  80. * @author ypw
  81. * @date 2019-08-29
  82. * @version 1.11.0
  83. * @des 用户拒绝权限请求并勾选不再询问后调用。可向用户进行权限说明,让用户去应用设置打开相应权限
  84. */
  85. private fun onNeverAskAgain() {
  86. showMissingPermissionDialog()
  87. }
  88. /**
  89. * 缺少权限-去APP设置打开
  90. */
  91. private fun showMissingPermissionDialog() {
  92. val builder = AlertDialog.Builder(this)
  93. builder.setMessage("${getString(R.string.app_name)}缺少必要权限,可能会导致部分功能无法使用\n\n请点击\"设置\"-\"权限\"-打开所需权限")
  94. builder.setNegativeButton("取消") { _, _ ->
  95. onPermissionDenied()
  96. }
  97. builder.setPositiveButton("设置") { _, _ ->
  98. startAppSettings()
  99. }
  100. builder.setCancelable(false)
  101. builder.show()
  102. }
  103. /**
  104. * 缺少权限-提示权限说明
  105. */
  106. private fun showRationaleDialog(success:() -> Unit) {
  107. val builder = AlertDialog.Builder(this)
  108. builder.setMessage("${getString(R.string.app_name)}缺少必要权限,可能会导致部分功能无法使用\n\n请再次确认是否开启")
  109. builder.setNegativeButton("取消") { _, _ ->
  110. onPermissionDenied()
  111. }
  112. builder.setPositiveButton("去确认") { _, _ ->
  113. success()
  114. }
  115. builder.setCancelable(false)
  116. builder.show()
  117. }
  118. /**
  119. * 打开系统设置,修改权限
  120. */
  121. private fun startAppSettings() {
  122. val intent = Intent(ACTION_APPLICATION_DETAILS_SETTINGS)
  123. intent.data = Uri.parse("package:$packageName")
  124. startActivity(intent)
  125. }
  126. override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
  127. super.onRequestPermissionsResult(requestCode, permissions, grantResults)
  128. if (requestCode == this.requestCode) {
  129. if (PermissionUtils.verifyPermissions(*grantResults)) {
  130. onPermissionSuccess()
  131. } else {
  132. if (!PermissionUtils.shouldShowRequestPermissionRationale(this, *permissions)) {
  133. onNeverAskAgain()
  134. } else {
  135. onPermissionDenied()
  136. }
  137. }
  138. }
  139. }
  140. }

简单用例

  1. import android.Manifest
  2. import android.os.Bundle
  3. import android.view.View
  4. class MainActivity : BasePermissionsActivity() {
  5. override fun onCreate(savedInstanceState: Bundle?) {
  6. super.onCreate(savedInstanceState)
  7. setContentView(R.layout.activity_main)
  8. }
  9. fun onClick(v: View) {
  10. val permission = arrayOf(
  11. Manifest.permission.READ_PHONE_STATE,
  12. Manifest.permission.READ_EXTERNAL_STORAGE,
  13. Manifest.permission.WRITE_EXTERNAL_STORAGE
  14. )
  15. onRequestPermission(permission)
  16. }
  17. override fun onPermissionSuccess() {
  18. println("权限请求成功")
  19. }
  20. override fun onPermissionDenied() {
  21. println("权限请求失败")
  22. }
  23. }

运行时权限

  1. group:android.permission-group.CONTACTS
  2. permission:android.permission.WRITE_CONTACTS
  3. permission:android.permission.GET_ACCOUNTS
  4. permission:android.permission.READ_CONTACTS
  5. group:android.permission-group.PHONE
  6. permission:android.permission.READ_CALL_LOG
  7. permission:android.permission.READ_PHONE_STATE
  8. permission:android.permission.CALL_PHONE
  9. permission:android.permission.WRITE_CALL_LOG
  10. permission:android.permission.USE_SIP
  11. permission:android.permission.PROCESS_OUTGOING_CALLS
  12. permission:com.android.voicemail.permission.ADD_VOICEMAIL
  13. group:android.permission-group.CALENDAR
  14. permission:android.permission.READ_CALENDAR
  15. permission:android.permission.WRITE_CALENDAR
  16. group:android.permission-group.CAMERA
  17. permission:android.permission.CAMERA
  18. group:android.permission-group.SENSORS
  19. permission:android.permission.BODY_SENSORS
  20. group:android.permission-group.LOCATION
  21. permission:android.permission.ACCESS_FINE_LOCATION
  22. permission:android.permission.ACCESS_COARSE_LOCATION
  23. group:android.permission-group.STORAGE
  24. permission:android.permission.READ_EXTERNAL_STORAGE
  25. permission:android.permission.WRITE_EXTERNAL_STORAGE
  26. group:android.permission-group.MICROPHONE
  27. permission:android.permission.RECORD_AUDIO
  28. group:android.permission-group.SMS
  29. permission:android.permission.READ_SMS
  30. permission:android.permission.RECEIVE_WAP_PUSH
  31. permission:android.permission.RECEIVE_MMS
  32. permission:android.permission.RECEIVE_SMS
  33. permission:android.permission.SEND_SMS
  34. permission:android.permission.READ_CELL_BROADCASTS

普通权限

  1. ACCESS_LOCATION_EXTRA_COMMANDS 定位权限
  2. ACCESS_NETWORK_STATE 网络状态权限
  3. ACCESS_NOTIFICATION_POLICY 通知 APP通知显示在状态栏
  4. ACCESS_WIFI_STATE WiFi状态权限
  5. BLUETOOTH 使用蓝牙权限
  6. BLUETOOTH_ADMIN 控制蓝牙开关
  7. BROADCAST_STICKY 粘性广播
  8. CHANGE_NETWORK_STATE 改变网络状态
  9. CHANGE_WIFI_MULTICAST_STATE 改变WiFi多播状态,应该是控制手机热点(猜测)
  10. CHANGE_WIFI_STATE 控制WiFi开关,改变WiFi状态
  11. DISABLE_KEYGUARD 改变键盘为不可用
  12. EXPAND_STATUS_BAR 扩展bar的状态
  13. GET_PACKAGE_SIZE 获取应用安装包大小
  14. INTERNET 网络权限
  15. KILL_BACKGROUND_PROCESSES 杀死后台进程
  16. MODIFY_AUDIO_SETTINGS 改变音频输出设置
  17. NFC 支付
  18. READ_SYNC_SETTINGS 获取手机设置信息
  19. READ_SYNC_STATS 数据统计
  20. RECEIVE_BOOT_COMPLETED 监听启动广播
  21. REORDER_TASKS 创建新栈
  22. REQUEST_INSTALL_PACKAGES 安装应用程序
  23. SET_TIME_ZONE 允许应用程序设置系统时间区域
  24. SET_WALLPAPER 设置壁纸
  25. SET_WALLPAPER_HINTS 设置壁纸上的提示信息,个性化语言
  26. TRANSMIT_IR 红外发射
  27. USE_FINGERPRINT 指纹识别
  28. VIBRATE 震动
  29. WAKE_LOCK 锁屏
  30. WRITE_SYNC_SETTINGS 改变设置
  31. SET_ALARM 设置警告提示
  32. INSTALL_SHORTCUT 创建快捷方式
  33. UNINSTALL_SHORTCUT 删除快捷方式
  34. 以上这些只是普通权限,我们开发的时候,正常使用就行了,需要的权限在清单文件配置即可。