Android 运行时权限处理
引言
Android 6.0 (API 23) 开始引入了运行时权限检查 (Permissions at Run Time),用户不需要在安装时同意授予应用权限,而是在应用运行时动态去申请所需要的权限,由用户决定是否授予权限,这样可以让用户更灵活的控制授予应用的权限,而不是必需在应用安装时就授予或者不授予应用请求的所有权限。例如一个应用同时申请了使用相机和定位服务的权限,用户可以只授该应用访问相机的权限,而不授予定位的权限。
权限的分类
不是所有权限都必须动态申请的,系统权限被分为两类:普通权限 (Normal Permissions),敏感权限(Dangerous permissions)。
- 普通权限:不涉及到用户敏感信息,应用只需要在
AndroidManifest
声明,用户同意安装应用,系统就会自动授予相应的权限,和 API 23 以前版本保持一致。 - 敏感权限:能够访问用户的敏感信息,如使用相机、联系人等权限。申请敏感权限时不仅需要在
AndroidManifest
声明,还需要在运行时申请,用户同意后才能获取到该权限。
不同 Android 版本对权限的处理
对于普通权限,Android 6.0 的处理方式是一样,即只要在 AndroidManifest
声明,用户安装了应用就会获取到权限。但对于敏感权限的处理就有所不同了,由于运行时权限是在 Android 6.0 才开始引入的,所以那些运行在老版本上的应用是没有对运行时权限做处理的,为了兼容旧版本的应用,Android 6.0 必须做不同处理。
- 在 Android 5.1 或者版本更低的设备上,Android 对普通和敏感权限的处理都是一样的,必须在
AndroidManifest
声明,用户也必须在安装时就授予相应的权限。 - 在 Android 6.0 或者更高版本的设备上,要看应用的
target SDK
版本,如果应用的target SDK
版本是 23 或者更高,那么应用就必须对运行时权限做处理,如果要申请敏感权限在AndroidManifest
中声明的同时,还需要在运行时动态请求相应的敏感权限,否则将无法获取敏感权限;如果应用的target SDK
版本是 22 或者更低,并且在AndroidManifest
中声明了敏感权限,那么用户必须在安装是就授予权限,运行时 Android 会默认应用拥有敏感权限,但这并不是说 target SDK 22 以下的应用就不用处理运行时敏感权限了,用户还是随时可以在应用的权限管理界面关掉相应的权限的,如果权限被用户手动关掉,那么运行时应用是没有权限的,所以应用在运行时还是要判断是否获得了所需要的权限。
如何检查应用是否有所需的敏感权限
如果应用需要敏感权限,那么在应用每次运行的时候都需要检查是否拥有权限,因为用户可以随时在权限管理界面关掉权限,运行以下代码检查应用是否具有权限:
int permission = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);
如果 permission
等于 PackageManager.PERMISSION_GRANTED
则代表应用已经拥有权限了,反之如果 permission
等于 PackageManager.PERMISSION_DENIED
则代表应用没有获得权限,需要再次申请。
如何在运行时申请敏感权限
这里以读取联系人权限为例:
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) { // 是否要显示问什么要获取权限的解释界面
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,Manifest.permission.READ_CONTACTS)) {
// 显示解释权限用途的界面,然后再继续请求权限
} else {
// 没有权限,直接请求权限
ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
}
}
代码执行时会弹出系统默认的请求权限对话框
请求权限对话框.png
上面一段有几处需要注意的:
shouldShowRequestPermissionRationale
函数是用来判断是否需要显示解释为什么需要该权限的界面,该函数在应用第一次安装的时候会返回false
,因此你可以直接请求任何需要的权限。如果用户以前拒绝了一个请求,这个方法将返回true
,那样的话你应该考虑在再次触发权限对话框之前显示一个解释请求用途之类的信息。当应用完全没有机会被授权的时候,该函数也会返回false
,比如用户在权限对话框中选择了"不再显示”,结果为false
说明用户明确不想授权,再弹解释界面也是没用。ActivityCompat.requestPermissions
这里我们调用的是ActivityCompat
的requestPermissions
,用户选择完成后会回调该Activity
的onRequestPermissionsResult
,但如果在Fragment
处理请求最好调用FragmentCompat. requestPermissions
(需要 android.support.v13),这样处理结果会回调到Fragment
的onRequestPermissionsResult
。MY_PERMISSIONS_REQUEST_READ_CONTACTS
是一个int
型值,是权限请求的标志,会在onRequestPermissionsResult
中返回,用来标志该回调是对应哪个请求的。
处理权限请求结果
如上面所说的,用户选择之后的结果会回调到 onRequestPermissionsResult
函数,根据requestCode
和 grantResults
判断结果:
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限申请通过!
} else {
// 悲剧了,用户不给权限
}
return;
}
}
}
来自:http://www.jianshu.com/p/9604d48178ce
Android 运行时权限处理的更多相关文章
- Android 运行时权限处理(from jianshu)
https://www.jianshu.com/p/e1ab1a179fbb 翻译的国外一篇文章. android M 的名字官方刚发布不久,最终正式版即将来临! android在不断发展,最近的更新 ...
- Android 运行时权限及APP适配
Android 6.0起,Android加强了权限管理,引入运行时权限概念.对于: 1. Android 5.1(API 22)及以前版本,应用权限必须声明在AndroidManifest.xml中, ...
- Android运行时权限
Android 6.0加入了运行时权限这一概念.对于危险权限,应用必须在使用的时候进行申请.可以使用命令行查看危险权限:adb shell pm list permissions -d -g CALE ...
- Android运行时权限开启问题
参考: http://www.cnblogs.com/whoislcj/p/6072718.html(重点这篇) https://www.jianshu.com/p/b4a8b3d4f587 http ...
- 谈谈Android 6.0运行时权限理解
前言 谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6. ...
- Android M新的运行时权限开发者需要知道的一切
android M 的名字官方刚发布不久,最终正式版即将来临!android在不断发展,最近的更新 M 非常不同,一些主要的变化例如运行时权限将有颠覆性影响.惊讶的是android社区鲜有谈论这事儿, ...
- Android M 新的运行时权限开发者需要知道的一切
android M 的名字官方刚发布不久,最终正式版即将来临!android在不断发展,最近的更新 M 非常不同,一些主要的变化例如运行时权限将有颠覆性影响.惊讶的是android社区鲜有谈论这事儿, ...
- Android PermissionUtils:运行时权限工具类及申请权限的正确姿势
Android PermissionUtils:运行时权限工具类及申请权限的正确姿势 ifadai 关注 2017.06.16 16:22* 字数 318 阅读 3637评论 1喜欢 6 Permis ...
- Android8.0运行时权限策略变化和适配方案
版权声明:转载必须注明本文转自严振杰的博客:http://blog.yanzhenjie.comAndroid8.0也就是Android O即将要发布了,有很多新特性,目前我们可以通过AndroidS ...
随机推荐
- 一个简单的html5页面在线速成工具!(当然本文主要说下他的成果的结构)
分享一个好玩的web app页面速成工具 当然主要是让大家看下他的原理 看着他的结构大家就该猜到这个了.这个是利用换页之后给当前div加了一个active,然后利用css控制效果 这个毫无疑问是采用最 ...
- 大熊君大话NodeJS之------FS文件模块
一,开篇分析 文件系统模块是一个简单包装的标准 POSIX 文件 I/O 操作方法集.可以通过调用 require("fs") 来获取该模块.文件系统模块中的所有方法均有异步和同步 ...
- C# 中excel操作
c#中设置Excel单元格格式 1.全表自动列宽 mysheet.Cells.Select(); mysheet.Cells.Columns.AutoFit(); 2.合并 excelRa ...
- solrcloud
@Test public void querySolrCloud(){ String zkHost = "127.0.0.1:2181"; String defaultCollec ...
- Spark之命令
Spark之命令 1.spark运行模式有4种: a.local 多有用测试, b. standalone:spark 集群模式,使用spark自己的调度方式. c. Yarn: 对Mapreduce ...
- C#利用Web Service实现短信发送(转)
通过编程方式实现短信息的发送对很多人来说是一件比较烦杂的事情,目前一般的解决方法是通过计算机和手机的连线,通过可对手机编程的语言编写相关的手机短信息程序来实现,而这种方法对于一般人来说是很难达到的,因 ...
- bootstrap-scrollspy
功能:用在导航栏上,用于滚动内容时动态对应导航标签 插件:scrollspy.js 要点:scrollspy用在导航栏.导航条上居多.body添加data-spy="scroll" ...
- gulp常用插件
本人就职于一家互联网小公司,根据自己的项目纪录一下常用的gulp插件,项目不是很大! 文章目录 1. gulp-load-plugins 2. yargs 3. del 4. gulp-filter ...
- php导出csv数据在浏览器中输出提供下载或保存到文件的示例
来源:http://www.jb51.net/article/49313.htm 1.在浏览器输出提供下载 /** * 导出数据到CSV文件 * @param array $data 数据 * @pa ...
- java中线程分两种,守护线程和用户线程。
java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...