文章目录
  1. 1. 运行时权限介绍
  2. 2. 运行时权限处理
    1. 2.1. 配置支持运行时权限
    2. 2.2. 检查并申请权限
  3. 3. 兼容
  4. 4. 相关开源项目
  5. 5. 参考信息

Android的权限系统(6.0之前版本)一直是首要的安全概念,因为这些权限只在安装的时候被询问一次。一旦安装了,APP可以在用户毫不知晓的情况下访问权限内的所有东西。7年了!权限系统终于被重新设计了。在Android6.0棉花糖,APP将不仅需要在安装的时候授予权限取,而且一些隐私敏感权限不得不在运行时一个一个询问用户授予权限。

运行时权限介绍

Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,
又新增了运行时权限动态检测,以下9个权限组都需要在运行时判断:

android6.0 permission dialog

运行时权限处理

这个新的运行时权限仅当我们设置targetSdkVersion to 23(这意味着你已经在23上测试通过了)才起作用,当然还要是M系统的手机。app在6.0之前的设备依然使用旧的权限系统。但这也只是一个临时的救急策略,用户还是可以在设置中取消授予的权限。如果用户取消了授权,愿调用函数只返回null或者0.
同一权限组组的任何一个权限被授权了,其他权限也自动被授权。例如,一旦WRITE_CONTACTS被授权了,APP也有READ_CONTACTS和GET_ACCOUNTS了。

配置支持运行时权限

声明目标SDK版本,我们需要在build.gradle中声明targetSdkVersion为23。

检查并申请权限

我们需要在用到权限的地方,每次都检查是否APP已经拥有权限。例如:

1
2
3
4
5
6
7
8
9
10
final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
private void insertDummyContactWrapper() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
insertDummyContact();
}

如果已有权限,insertDummyContact()会执行。否则,requestPermissions被执行来弹出请求授权对话框,如下:

android6.0 permission dialog

不论用户同意还是拒绝,activity的onRequestPermissionsResult会被回调来通知结果(通过第三个参数),grantResults,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
insertDummyContact();
} else {
// Permission Denied
Toast.makeText(MainActivity.this, "WRITE_CONTACTS Denied", Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

兼容

Android6.0之前版本的兼容,谷歌已经替我们想到了这个问题,可以采用v4包中的相应方法处理。主要有以下方法:

1
2
3
4
5
6
ContextCompat.checkSelfPermission();
ActivityCompat.requestPermissions();
ActivityCompat.OnRequestPermissionsResultCallback();
ActivityCompat.shouldShowRequestPermissionRationale();
FragmentCompat.requestPermissions();
FragmentCompat.shouldShowRequestPermissionRationale();

PS: 在Fragment中申请权限,使用ActivityCompat.requestPermissions, 会回调到Activity的onRequestPermissionsResult

相关开源项目

通过上面的权限实现,我们发现权限处理逻辑比较复杂。为此,很多第三方库诞生了。

参考信息

参考地址:
https://developer.android.com/reference/android/Manifest.permission_group.html
https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
https://developer.android.com/training/permissions/best-practices.html


本文地址 http://ihongqiqu.com/2015/12/23/Android-6-permission/ 作者为 Zhenguo

author:Zhenguo
Author: Zhenguo      Blog: http://ihongqiqu.com/     Email: jinzhenguo1990@gmail.com
I have almost 6 years of Android application development experience and have a keen interested in the latest emerging technologies. I use my spare time to turn my experience, ideas and love for Android tech into informative articles, tutorials and more in hope to help others and learn more.
文章目录
  1. 1. 运行时权限介绍
  2. 2. 运行时权限处理
    1. 2.1. 配置支持运行时权限
    2. 2.2. 检查并申请权限
  3. 3. 兼容
  4. 4. 相关开源项目
  5. 5. 参考信息
返回顶部