一、什么是运行时权限
Android的运行时权限是在6.0系统中加入的权限功能。在此之前,一款应用程序的权限申请以列表的形式呈现在安装过程中,如果用户不认可该应用申请的权限,那么拒绝安装就可以了。而运行时权限,是在应用程序使用过程中再对某一项权限进行授权。即使用户拒绝了其中某个授权申请,仍然可以使用这个应用程序的其他功能,而不是像以前那样无法安装它。
PS:https://developer.android.google.cn/reference/android/Manifest.permission可查看Android系统中完整的权限列表。
二、权限的分类
1.普通权限:指那些不会直接威胁到用户的安全和隐私的权限,对于普通权限,系统会自动帮用户进行授权。
2.危险权限:指那些可能触及用户隐私,或者对设备安全性造成影响的权限,对于危险权限,必须向用户申请授权才可使用相关功能。
下面是危险权限的列表,一共9组24个权限。
如果是属于上述表格中的权限,那么就要进行运行时权限处理,如果不在上述表格中,那么只需要在AndroidManifest.xml文件中添加一行权限声明即可。
PS:表格中的每一个权限都属于一个权限组,我们在进行运行时权限处理时使用的是权限名,一旦用户同意授权了,那么该权限对应的权限组中所有的其他权限也会同时被授权。
三、单条运行时权限申请
1.判断当前是否已经授权,如果已经授权则直接进行相关操作(样例是打电话),如果没有授权则申请授权
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE},CALL_PHONE_REQUEST_CODE);
} else {
call();
}
判断语句中的前半部分是用来检查权限的,返回值是一个int值,即是否已经授权的结果。传入了两个参数,第一个参数是Context,第二个参数是String类型的权限,在Manifest.permission中有其静态常量。判断语句的后半部分是已经授权的int值,没有授权的情况是PackageManager.PERMISSION_DENIED。ActivityCompat.requestPermissions()方法用于向用户申请授权,传入了三个参数,第一个参数是Context,第二个参数是String[]类型,我们将需要申请的所有权限添加其中,第三个参数是请求码,保持唯一即可,接下来作为判断条件。
2.重写onRequestPermissionsResult()方法,处理申请授权之后的结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case CALL_PHONE_REQUEST_CODE:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
call();
} else {
Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
onRequestPermissionsResult()作为回调方法,通过第一个参数requestCode来判断申请的是什么权限,这个请求码也就是我们在第一步中传入的第三个参数,而授权的结果会封装在grantResults参数当中。
四、多条运行时权限的申请
1.采用集合将需要申请的多条运行时权限放入其中,再一起发出申请
List<String> permissionList = new ArrayList<>();
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED){
permissionList.add(Manifest.permission.READ_PHONE_STATE);
}
if(!permissionList.isEmpty()){
String[] permissions = permissionList.toArray(new String[permissionList.size()]);
ActivityCompat.requestPermissions(MainActivity.this,permissions,REQUEST_WRITE_SD_CODE);
}
2.onRequestPermissionsResult()方法也略有变化
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case REQUEST_WRITE_SD_CODE:
if(grantResults.length > 0){
for(int result : grantResults){
if(result != PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show();
finish();
return;
}
}
}
break;
default:
break;
}
}
因为是多条权限的申请,在这里我们对申请结果进行遍历,只要有一条没有授权则不能进行后续操作。