基于 permissionsdispatcher 库,创建的 BasePermissionsActivity 基类。
背景:permissionsdispatcher通过注解的使用方式处理权限申请,在单个页面的时候比较方便。
但是当需要进行权限申请的页面比较多是的时候,每个页面都需要重复相同的代码逻辑。
优点:
- 直接继承 BasePermissionsActivity
- 申请默认权限
- 申请指定权限
- 重写权限申请成功和失败回调
- 可重写 onShowRationale() 对用户首次拒绝的权限进行说明
permissionsdispatcher 依赖
dependencies {
......
// 运行时权限
implementation ("com.github.hotchemi:permissionsdispatcher:3.3.1"){
exclude module: "support-v13"
}
}
BasePermissionsActivity 代码
import android.Manifest
import android.support.v7.app.AppCompatActivity
import android.support.v4.app.ActivityCompat
import permissions.dispatcher.*
import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
import android.content.Intent
import android.net.Uri
import android.support.v7.app.AlertDialog
/**
* @author ypw
* @date 2019-08-29
* @version 1.11.0
* @des 动态权限检查基类
*/
abstract class BasePermissionsActivity : AppCompatActivity() {
/**
* @author ypw
* @date 2019-08-29
* @version 1.11.0
* @des 默认申请权限
*/
val needsPermission = arrayOf(
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
private val requestCode: Int = 0
/**
* @author ypw
* @date 2019-08-29
* @version 1.11.0
* @des 请求默认权限
*/
fun onRequestPermission() {
onRequestPermission(needsPermission)
}
/**
* @author ypw
* @date 2019-08-29
* @version 1.11.0
* @des 请求指定权限
*/
fun onRequestPermission(permissions: Array<String>) {
if (PermissionUtils.hasSelfPermissions(this, *permissions)) {
onPermissionSuccess()
} else {
if (PermissionUtils.shouldShowRequestPermissionRationale(this, *permissions)) {
onShowRationale(permissions)
} else {
ActivityCompat.requestPermissions(this, permissions, requestCode)
}
}
}
/**
* @author ypw
* @date 2019-08-29
* @version 1.11.0
* @des 权限请求成功后调用
*/
abstract fun onPermissionSuccess()
/**
* @author ypw
* @date 2019-08-29
* @version 1.11.0
* @des 权限请求失败后调用
*/
abstract fun onPermissionDenied()
/**
* @author ypw
* @date 2019-08-29
* @version 1.11.0
* @des 首次权限请求拒绝后,再次权限请求时调用。可向用户进行权限说明
*/
open fun onShowRationale(permissions: Array<String>) {
showRationaleDialog {
ActivityCompat.requestPermissions(this, permissions, requestCode)
}
}
/**
* @author ypw
* @date 2019-08-29
* @version 1.11.0
* @des 用户拒绝权限请求并勾选不再询问后调用。可向用户进行权限说明,让用户去应用设置打开相应权限
*/
private fun onNeverAskAgain() {
showMissingPermissionDialog()
}
/**
* 缺少权限-去APP设置打开
*/
private fun showMissingPermissionDialog() {
val builder = AlertDialog.Builder(this)
builder.setMessage("${getString(R.string.app_name)}缺少必要权限,可能会导致部分功能无法使用\n\n请点击\"设置\"-\"权限\"-打开所需权限")
builder.setNegativeButton("取消") { _, _ ->
onPermissionDenied()
}
builder.setPositiveButton("设置") { _, _ ->
startAppSettings()
}
builder.setCancelable(false)
builder.show()
}
/**
* 缺少权限-提示权限说明
*/
private fun showRationaleDialog(success:() -> Unit) {
val builder = AlertDialog.Builder(this)
builder.setMessage("${getString(R.string.app_name)}缺少必要权限,可能会导致部分功能无法使用\n\n请再次确认是否开启")
builder.setNegativeButton("取消") { _, _ ->
onPermissionDenied()
}
builder.setPositiveButton("去确认") { _, _ ->
success()
}
builder.setCancelable(false)
builder.show()
}
/**
* 打开系统设置,修改权限
*/
private fun startAppSettings() {
val intent = Intent(ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:$packageName")
startActivity(intent)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == this.requestCode) {
if (PermissionUtils.verifyPermissions(*grantResults)) {
onPermissionSuccess()
} else {
if (!PermissionUtils.shouldShowRequestPermissionRationale(this, *permissions)) {
onNeverAskAgain()
} else {
onPermissionDenied()
}
}
}
}
}
简单用例
import android.Manifest
import android.os.Bundle
import android.view.View
class MainActivity : BasePermissionsActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun onClick(v: View) {
val permission = arrayOf(
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
onRequestPermission(permission)
}
override fun onPermissionSuccess() {
println("权限请求成功")
}
override fun onPermissionDenied() {
println("权限请求失败")
}
}
运行时权限
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
普通权限
ACCESS_LOCATION_EXTRA_COMMANDS 定位权限
ACCESS_NETWORK_STATE 网络状态权限
ACCESS_NOTIFICATION_POLICY 通知 APP通知显示在状态栏
ACCESS_WIFI_STATE WiFi状态权限
BLUETOOTH 使用蓝牙权限
BLUETOOTH_ADMIN 控制蓝牙开关
BROADCAST_STICKY 粘性广播
CHANGE_NETWORK_STATE 改变网络状态
CHANGE_WIFI_MULTICAST_STATE 改变WiFi多播状态,应该是控制手机热点(猜测)
CHANGE_WIFI_STATE 控制WiFi开关,改变WiFi状态
DISABLE_KEYGUARD 改变键盘为不可用
EXPAND_STATUS_BAR 扩展bar的状态
GET_PACKAGE_SIZE 获取应用安装包大小
INTERNET 网络权限
KILL_BACKGROUND_PROCESSES 杀死后台进程
MODIFY_AUDIO_SETTINGS 改变音频输出设置
NFC 支付
READ_SYNC_SETTINGS 获取手机设置信息
READ_SYNC_STATS 数据统计
RECEIVE_BOOT_COMPLETED 监听启动广播
REORDER_TASKS 创建新栈
REQUEST_INSTALL_PACKAGES 安装应用程序
SET_TIME_ZONE 允许应用程序设置系统时间区域
SET_WALLPAPER 设置壁纸
SET_WALLPAPER_HINTS 设置壁纸上的提示信息,个性化语言
TRANSMIT_IR 红外发射
USE_FINGERPRINT 指纹识别
VIBRATE 震动
WAKE_LOCK 锁屏
WRITE_SYNC_SETTINGS 改变设置
SET_ALARM 设置警告提示
INSTALL_SHORTCUT 创建快捷方式
UNINSTALL_SHORTCUT 删除快捷方式
以上这些只是普通权限,我们开发的时候,正常使用就行了,需要的权限在清单文件配置即可。