欢迎访问我的个人博客 传送门

从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限。它还让用户可以对应用的功能进行更多控制;例如,用户可以选择为相机应用提供相机访问权限,而不提供设备位置的访问权限。用户可以随时进入应用的“Settings”屏幕调用权限。

正常权限和危险权限

系统权限分为几个保护级别。需要了解的两个最重要保护级别是正常权限和危险权限,如果应用声明其需要正常权限,系统会自动向应用授予该权限,如:访问网络。如果应用声明其需要危险权限,则用户必须明确向应用授予该权限,如:访问联系人、读写权限。

正常权限

官网可查 点击查询

ACCESS_LOCATION_EXTRA_COMMANDS

ACCESS_NETWORK_STATE

ACCESS_NOTIFICATION_POLICY

ACCESS_WIFI_STATE

BLUETOOTH

BLUETOOTH_ADMINbaidu_push

BROADCAST_STICKY

CHANGE_NETWORK_STATE

CHANGE_WIFI_MULTICAST_STATE

CHANGE_WIFI_STATE

DISABLE_KEYGUARD

EXPAND_STATUS_BAR

GET_PACKAGE_SIZE

INSTALL_SHORTCUT

INTERNET

KILL_BACKGROUND_PROCESSES

MODIFY_AUDIO_SETTINGS

NFC

READ_SYNC_SETTINGS

READ_SYNC_STATS

RECEIVE_BOOT_COMPLETED

REORDER_TASKS

REQUEST_IGNORE_BATTERY_OPTIMIZATIONS

REQUEST_INSTALL_PACKAGES

SET_ALARM

SET_TIME_ZONE

SET_WALLPAPER

SET_WALLPAPER_HINTS

TRANSMIT_IR

UNINSTALL_SHORTCUT

USE_FINGERPRINT

VIBRATE

WAKE_LOCK

WRITE_SYNC_SETTINGS

危险权限

可通过adb 命令获取 adb shell pm list permissions -d -g

group:android.permission-group.RCS_PERMISSION

group:com.google.android.gms.permission.CAR_INFORMATION

permission:com.google.android.gms.permission.CAR_VENDOR_EXTENSION

permission:com.google.android.gms.permission.CAR_MILEAGE

permission:com.google.android.gms.permission.CAR_FUEL

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.ANSWER_PHONE_CALLS

permission:android.permission.READ_PHONE_NUMBERS

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:com.google.android.gms.permission.CAR_SPEED

permission:android.permission.ACCESS_COARSE_LOCATION

group:android.permission-group.STORAGE

permission:android.permission.READ_EXTERNAL_STORAGE

permission:android.permission.WRITE_EXTERNAL_STORAGE

group:com.sina.weibo.permission-group

permission:com.sina.weibo.permission.USER

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

从上面的权限列表中可以看出危险权限都是分组的,如果应用请求其清单中列出的危险权限,而应用在同一权限组中已有另一项危险权限,则系统会立即授予该权限,而无需与用户进行任何交互。例如,如果某应用已经请求并且被授予了 READ_CONTACTS 权限,然后它又请求 WRITE_CONTACTS,系统将立即授予该权限。

请求权限

这里以申请日历读写权限为例

1.在 AndroidMainifest 中声明所需权限

2.检查权限

private fun checkPermissions(): Boolean {

return when (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR)) {

PackageManager.PERMISSION_GRANTED -> {//有此权限

true

}

PackageManager.PERMISSION_DENIED -> {//无此权限

false

}

else -> false

}

}

这里用到系统提供的 ContextCompat.checkSelfPermission 方法,用于检测某个权限是否已经被授予,方法返回值为 PackageManager.PERMISSION_GRANTED 表示已权限,为PackageManager.PERMISSION_DENIED 表示无此权限需要进行申请授权。

3.申请权限

private fun requestPermissions() {

if (ActivityCompat.shouldShowRequestPermissionRationale(this,

Manifest.permission.READ_CALENDAR)) {

// 是否需要向用户解释为何申请权限

toast(this,"需要此权限管理日历")

} else {

ActivityCompat.requestPermissions(this,

arrayOf(Manifest.permission.READ_CALENDAR),

1)

}

}

ActivityCompat.shouldShowRequestPermissionRationale 方法 用于在实际显示权限对话框之前是否显示一个对正在请求权限的解释,在app第一次安装的时候。这个方法会返回false,因此你可以直接请求任何需要的权限。

如果用户以前拒绝了一个请求,则分为两种情况:

如果用户仅拒绝没有点不再提示,这个方法将返回 true

如果用户拒绝并点击不再提示,这个方法将返回 false

ActivityCompat.requestPermissions 方法 用于申请权限,第二个参数为 所需权限数组,也就是可申请一个,或多个权限。第三个参数为 requestCode 回调的时候使用

4.处理权限申请回调

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {

super.onRequestPermissionsResult(requestCode, permissions, grantResults)

when (requestCode) {

1 -> {

if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

toast(this, "已授权")

} else {

toast(this, "未授权")

}

}

else -> {

}

}

}

处理权限要实现 onRequestPermissionsResult 方法,该方法有三个参数

requestCode 和申请权限时 requestCode 对应,

permissions 申请的权限数组

grantResults 申请结果

完整的代码如下:

fun click(view: View?) {

when (view?.id) {

R.id.bt_query_permissions -> when (checkPermissions()) {

true -> toast(this, "有权限")

false -> toast(this, "无权限")

}

R.id.bt_request_permissions -> requestPermissions()

}

}

private fun checkPermissions(): Boolean {

return when (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR)) {

PackageManager.PERMISSION_GRANTED -> {//有此权限

true

}

PackageManager.PERMISSION_DENIED -> {//无此权限

false

}

else -> false

}

}

private fun requestPermissions() {

if (ActivityCompat.shouldShowRequestPermissionRationale(this,

Manifest.permission.READ_CALENDAR)) {

toast(this,"需要此权限管理日历")

} else {

ActivityCompat.requestPermissions(this,

arrayOf(Manifest.permission.READ_CALENDAR),

1)

}

}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {

super.onRequestPermissionsResult(requestCode, permissions, grantResults)

when (requestCode) {

1 -> {

if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

toast(this, "已授权")

} else {

toast(this, "未授权")

}

}

else -> {

}

}

}

推荐使用 RxPermissions

RxPermissions 是一个基于 RxJava 实现的权限框架,比使用 Android 自带的 API 方便很多,可扩展性高。GitHub 地址

引入

这里以 Rxjava2 为例

repositories {

jcenter() // If not already there

}

dependencies {

//compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar' // Rxjava1

compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar' // Rxjava2

compile "io.reactivex.rxjava2:rxjava:2.1.7"

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

}

请求权限

request 可申请一个或多个权限 直接返回是否授权成功

val rxPermissions = RxPermissions(this)

rxPermissions.request(Manifest.permission.READ_CALENDAR)

.subscribe({ t ->

if (t) {

toast(this, "已授权")

} else {

toast(this, "未授权")

}

})

requestEach or ensureEach 来分别获取每一个权限请求的结果

rxPermissions.requestEach(Manifest.permission.READ_CALENDAR, Manifest.permission.CAMERA)

.subscribe({ t ->

when {

t.granted -> toast(this, "${t.name} 已授权")

t.shouldShowRequestPermissionRationale -> toast(this, "${t.name} 未授权")

else -> toast(this, "${t.name} 已拒绝,并不提示")

}

})

这里的 shouldShowRequestPermissionRationale 参照上文 权限申请

最后

权限申请的坑还有很多,特别是在国产手机上有各种各样的bug,这个就要具体踩坑,具体解决了

android 权限管理框架,Android 运行时权限管理最佳实践相关推荐

  1. 聊一聊Android 6.0的运行时权限

    Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...

  2. Android RuntimePermissions运行时权限:单个运行时权限申请简例

    Android RuntimePermissions运行时权限:单个运行时权限申请简例 Android运行时权限申请的框架结构和步骤比较简单和固定,一般现状代码启动后检查当前的Android SDK版 ...

  3. 安卓从业者应该关注:Android 6.0的运行时权限

    Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...

  4. Android M 新的运行时权限开发者需要知道的一切

    android M 的名字官方刚发布不久,最终正式版即将来临! android在不断发展,最近的更新 M 非常不同,一些主要的变化例如运行时权限将有颠覆性影响.惊讶的是android社区鲜有谈论这事儿 ...

  5. android权限允许,android – 允许多次运行时权限

    我正在编写代码,要求在组中的 android 6.0上获得多个运行时权限.一切都很好,我为此做了一些很好的例子,但仍然有问题. 在ActivityCompat.shouldShowRequestPer ...

  6. android申请多个运行时权限,Android 6.0(API 23) 运行时权限(二)之权限申请

    Android M 在上一篇中简单介绍了运行时权限,今天就讲讲怎么去申请权限.这个项目中本来用了一个第三方的权限框架,但是不太好用,我就在github上选择了start最多的PermissionsDi ...

  7. android方法数据库的权限,Android数据存储,运行时权限

    Android存储目录 Android的底层支持是Linux,不同于Windows,没有分盘的概念,是以文件夹形式呈现,可以理解为一个应用就是一个用户. data目录 手机内部存储目录(手机本身内存) ...

  8. (调用系统电话薄)运行时权限的基本使用

    GitHub项目地址: https://github.com/Skymqq/RuntimePermissionTest.git 运行时权限是Android6.0系统引入的新特性,那么为何要引入这种运行 ...

  9. Android 6.0运行时权限管理

    运行时权限管理 定义: 之前我们的App需要权限,只需在manifest中申明,用户安装后,一切申明的权限都可使用. 但是Android 6.0以后Android M把权限管理做了加强处理,除了需要在 ...

  10. Android 6.0 运行时权限处理完全解析

    一.概述 随着Android 6.0发布以及普及,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化.对于6.0的几个主要的变化,查看查看官网的这篇文章http:// ...

最新文章

  1. python编程入门教学电子书-Python编程入门电子书教程,看这几个就够了
  2. Linux7静默安装Oracle11g教程,亲测实用有效!
  3. linux共享库的运行方式,Linux下动态共享库加载及使用详解
  4. 【javascript权威指南】类型转换
  5. SAP S/4HANA Service Management和SAP FSM基于CPI的集成场景介绍
  6. 【面向对象】面向对象程序设计测试题2-Java基本语法测试题
  7. 个性化网管软件快速实现方法
  8. UA MATH563 概率论的数学基础 中心极限定理19 概率测度的全变差收敛 Skorohod定理
  9. 苹果cms海螺大橙子首途v7模板源码
  10. 魔兽争霸III显示器设置分辨率 修改注册表单实现
  11. 太阁5 800人物 喜好
  12. Java工作流管理系统(activity6.0)
  13. 拟一维喷管流动的数值解——亚声速-超声速等熵喷管流动的非守恒型CFD解法(MacCormack方法)
  14. 研究生入门,如何高效阅读论文
  15. 轻量快速的CI工具Drone快速入门
  16. 《EXPLAINING AND HARNESSING ADVERSARIAL EXAMPLES》阅读笔记
  17. 计算机与技术专业学e语言庅,计算机科学与技术专业课程有哪些 主要学什吗
  18. 版权概念小结(音乐方面)
  19. 树莓派配置frp实现内网穿透
  20. 满足你的好奇,手动拆解示波器,了解机内高科技

热门文章

  1. Chrome 开发者工具无法显示服务器正常返回的 HTTP 请求 - Failed to load response data
  2. SAP Spartacus和Table相关的配置结构ResponsiveTableConfiguration
  3. Angular jasmine TestBed.configureTestingModule的工作原理
  4. Angular应用的index.html
  5. 另一种办法直接在宿主机上的文件夹内查看Docker镜像运行的日志文件
  6. context set_parameter all_req_parameters /iwfnd/if_sodata_types=gcs_iwf_context
  7. SAP UI5 sap.ui.core.OpenState.CLOSED Dialog open and close
  8. how is ui5 resource root calculated
  9. Jerry本地安装SAP Kyma的一些失败尝试
  10. SAP UI5 router的初始化逻辑