android6.0运行时权限使用流程

前言:

本文不涉及第三方的类库和工具,只是原生的操作流程


一、简介

Android6.0 之前,用户安装 app ,会根据声明的权限生成一个权限列表,只有用户同意才能完成安装,而用户一般也不会注意这些权限,有可能会造成一些私密权限的泄漏,从而威胁到我们手机本身的信息安全!

Android6.0之后,运行时权限解决了这一问题,用户可以直接安装 app ,一些高危权限会在应用运行的过程中动态申请,我们可以选择同意或者拒绝,也可以在设置界面对每个 app 的权限进行查看和修改。

二、权限简介

官网上有句话,系统权限分为几个保护级别,需要了解的最重要的两个是 正常权限危险权限 ,而运行时权限就是针对危险权限而言的。

  • 危险权限官网定义:

危险权限涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如,能够读取用户的联系人属于危险权限。如果应用声明其需要危险权限,则用户必须明确向应用授予该权限。

  • 危险权限种类:

image

注意:左侧为权限组,右侧为权限组的具体权限,同一组内的任何一个权限被授权了,其他权限也自动被授权,系统只告诉用户应用需要的权限组,而不告知具体权限!

  • 使用流程
  1. 需要将 app 的 targetSdkVersion 设置到 23 及其以上,这样才有可能触发运行时权限。

  2. 在AndroidManifest文件中添加所需要的权限。

  3. 先检查系统版本,如果系统在 6.0 以上,采取运行时权限,版本名称和版本号参考官网:https://developer.android.com/reference/android/os/Build.VERSION_CODES.html

1
Build.VERSION.SDK_INT >= 23
  1. 几个重要的 API
1
2
3
4
5
6
7
8
9
10
检查某个权限是否被授予 ,以相机权限为例
if ( ContextCompat.checkSelfPermission ( this,Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED ) {
//申请相机权限操作
}else{
//相机权限已申请操作
}
1
2
3
4
5
6
7
8
9
该方法只有在用户在上一次已经拒绝过你的这个权限申请。也就是说
,用户已经拒绝一次了,你又弹个授权框,你需要给用户一个解释,为什么要授权,
则使用该方法,
只有第一次被拒绝,当第二次申请时, if 条件为 true,其他都为 false
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
}
1
2
3
4
5
6
7
8
9
10
申请相机权限操作
第一个参数是Context;
第二个参数是需要申请的权限的字符串数组;
第三个参数为requestCode, 主要用于回调时候监测
其中第二个参数支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
CAMERA_REQUEST_CODE);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
此方法是权限申请的回调方法,在此方法中处理权限申请成功或失败后的操作。
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case CAMERA_REQUEST_CODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//权限申请成功操作
} else {
//权限申请失败
//用户勾选了禁止后不再询问,提示用户手动打开权限
}
return;
}
}
}
  1. 完整的操作流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//判断系统版本是否大于23
private boolean isRequestPermission() {
return Build.VERSION.SDK_INT >= 23;
}
//自定义请求权限
private void requestPermission() {
if (!isRequestPermission()) {
return;
}
//检查是否已经拥有该权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
//判断是否是第二次申请,(第一次被用户拒绝),如果是的话,做一些说明,一般是弹框说明
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
//弹出一个dialog,说明第二次请求原因
new AlertDialog.Builder(this)
.setMessage("申请照相机权限")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA},
CAMERA_REQUEST_CODE
);
}
}).show();
} else {//不是的话就执行申请操作
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{},
CAMERA_REQUEST_CODE
);
}
} else {
//相机权限已申请操作
}
}
/**
* 权限申请回调
*
* @param requestCode 请求码
* @param permissions 请求的权限列表
* @param grantResults 请求的结果列表
*/
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case CAMERA_REQUEST_CODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//权限申请成功操作
} else {
//权限申请失败
//用户勾选了禁止后不再询问,提示用户手动打开权限
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)){
Toast.makeText(MainActivity.this,"请在设置列表打开相机权限",Toast.LENGTH_SHORT).show();
}
}
return;
}
}
}
  1. 有几位大神总结的很不错,附上链接

Hongyang大神

郭霖大神