您的位置:首页 > 移动开发 > Android开发

Android 6.0及以上版本的运行时权限介绍

2016-07-30 15:38 465 查看
<span style="color: rgb(85, 85, 85); font-family: Lato, 'PingFang SC', 'Microsoft YaHei', sans-serif; font-size: 22px; line-height: 22px;">运行时权限介绍</span>


Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,

又新增了运行时权限动态检测,以下权限都需要在运行时判断:

身体传感器
日历
摄像头
通讯录
地理位置
麦克风
电话
短信
存储空间


运行时权限处理

Android6.0系统默认为targetSdkVersion小于23的应用默认授予了所申请的所有权限,

所以如果你以前的APP设置的targetSdkVersion低于23,在运行时也不会崩溃,

但这也只是一个临时的救急策略,用户还是可以在设置中取消授予的权限。
声明目标SDK版本

我们需要在build.gradle中声明targetSdkVersion为23
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"

defaultConfig {
applicationId "com.yourcomany.app
minSdkVersion 18
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}


但这也只是一个临时的救急策略,用户还是可以在设置中取消授予的权限。
检查并申请权限
我们需要在用到权限的地方,每次都检查是否APP已经拥有权限,
比如我们有一个下载功能,需要写SD卡的权限,
我们在写入之前检查是否有WRITE_EXTERNAL_STORAGE权限,没有则申请权限

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//申请WRITE_EXTERNAL_STORAGE权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
}



用户选择允许或拒绝后,会回调onRequestPermissionsResult方法, 该方法类似于onActivityResult
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
doNext(requestCode,grantResults);
}

我们接着需要根据requestCode和grantResults(授权结果)做相应的后续处理

private void doNext(int requestCode, int[] grantResults) {
if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
} else {
// Permission Denied
}
}
}


运行时权限介绍

一直以来,为了保证最大的安全性,安装Android应用时,系统总是让用户选择是否同意该应用所需的所有权限。一旦安装应用,就意味着该应用所需的所有权限均已获得。若在使用某个功能时用到了某个权限,系统将不会提醒用户该权限正在被获取(比如微信需要使用摄像头拍照,在Android 6.0以前的设备上,用户将不会被系统告知正在使用“使用系统摄像头”的权限)。
这在安全性上是个隐患:在不经用户同意的情况下,一些应用在后台可以自由地收集用户隐私信息而不被用户察觉。
从Android
6.0版本开始,这个隐患终于被消除了:在安装应用时,该应用无法取得任何权限!相反,在使用应用的过程中,若某个功能需要获取某个权限,系统会弹出一个对话框,显式地由用户决定是否将该权限赋予应用,只有得到了用户的许可,该功能才可以被使用。

运行时权限无疑提升了安全性,有效地保护了用户的隐私,这对于用户来说确实是个好消息,但对于开发者来说简直就是噩梦:因为这需要开发者在调用方法时,检查该方法使用了什么系统权限——这仿佛颠覆了传统的编程的逻辑——开发者编写每一句代码时都得小心翼翼,否则应用可能随时崩溃。

在程序中,设置目标SDK版本(targetSDKVersion)为23及以上时(这意味着程序可以在Android
6.0及以上的版本中运行),将应用安装在Android 6.0及以上机型中,运行时权限功能才能生效;若将其安装在Android 6.0以前的机型中,权限检查仍将仅仅发生在安装应用时。


运行时权限与各版本间的兼容性问题

假如将一个早期版本的应用安装在Android 6.0版本的机型上,应用是不会崩溃的,因为这只有两种情况:1)该应用的targetSDKVersion < 23,在这种情况下,权限检查仍是早期的形式(仅在安装时赋予权限,使用时将不被提醒);2)该应用的targetSDKVersion ≥ 23时,则将使用新的运行时权限规则。
所以,这个早期版本的应用将运行如常。不过,将该应用安装在Android 6.0上,且targetSDKVersion ≥ 23时,用户仍然可以随时手动撤销权限,当然这种做法不被官方推荐。
不被推荐的原因是,这种做法容易导致应用崩溃。若targetSDKVersion
< 23,当然不会出问题;若早期应用的targetSDKVersion ≥ 23,在使用应用时手动撤消了某个权限,那么程序在调用了需要这个权限才能执行的方法时,应用什么也不做,若该方法还有返回值,那么会根据实际情况返回 0 或者 null。

若上述调用的方法没有崩溃,那么这个方法被其他方法调用时也会因为返回值是 0 或者 null 而崩溃。

不过好消息是,用户几乎不会手动撤销已经赋予给应用的权限。

说了这么多,在避免应用崩溃的前提下,适配新的运行时权限功能才是王道:对于那些在代码中并未支持运行时权限的应用,请将targetSDKVersion设置为 < 23,否则应用有崩溃隐患;若代码中支持了运行时权限,再将targetSDKVersion设置为 ≥ 23。

请注意:在Android Studio中新建Project时,会自动赋予targetSDKVersion为最新版本,若您的应用还暂时无法完全支持运行时权限功能,建议首先将targetSDKVersion手动设置为22。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: