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

<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。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值