运行时权限是在6.0之后引用的,起到的作用是什么呐?就是一些软件会申请很多很多的权限,但是有很多权限在这个软件上也用不到,但是你又不得不同意,否则只能选择不安装。但是有了运行时权限,用户在安装软件的时候,不需要一次性的授权所有的权限,而是在使用过程中再对某一项权限进行申请。例如一个美图软件需要申请访问短信和彩信的权限,这样即使我们拒绝通过这个权限,我们还是可以继续使用这个软件,而不像之前那样直接无法使用这个软件。
但是频繁的授权对于用户来说也是一个很繁琐的过程。Android现在把所有的权限分为两种:一种是普通的权限,一种是危险的权限。普通权限是指那些不会直接威胁到用户的安全和隐私的权限,对于这类权限的申请,系统会自动帮我们进行授权;危险权限则是会直接威胁到用户的安全和隐私的,或者会对设备安全性造成影响的权限,这类权限必须经过用户点头动手同意,否则程序就不能使用相应的功能。
所以,在Android的上百多种权限里,普通权限不用记,只需要记住危险权限;危险权限一共9组24个:
运行时权限就是先检查有没有被用户授权,如果被授权,就运行,如果没有,就询问,再判断。
1.检查用户是否授权,这里的例子是拨打电话:
一个拨打电话的方法:
private void call() {
try {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
} catch (SecurityException e) {
e.printStackTrace();
}
}
在点击button的时候,进行权限检查:
case R.id.rt_callphone:
if (ContextCompat.checkSelfPermission(RT_Main.this, Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(RT_Main.this,
new String[]{Manifest.permission.CALL_PHONE}, 1);
} else {
call();
}
break;
检查权限是用的ContextCompat.checkSelfPermission()方法,checkSelfPermission()方法接受的是两个参数,第一个参数是context,第二个参数是具体的权限名。得到的返回值和PackageManager.PERMISSION_GRANTED做比较,如果相等,就说明已经授权,执行else;反之没有执行ActivityCompat.requestPermissions()方法来向用户申请授权,requestPermissions()方法传入三个参数,第一个context;第二个是String数组,把我们需要申请的权限名称放在数组,这里只放了一个,也可以放好多个;第三个是请求码,要输入一个唯一值;在执行完ActivityCompat.requestPermissions()方法后,系统会给用户弹出一个申请权限的对话框,不管用户是拒绝还是同意,都会回调下面的onRequsetPermissionsResult()方法,:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
call();
} else {
Toast.makeText(this, "You denied the call permission", Toast.LENGTH_SHORT).show();
}
break;
}
}
授权的结果会放在数组grantResults里面,再根据结果选择运行。
GitHub的开源库-------Easypermissions的使用
上面的运行时权限份三部:1.检查运行时权限,2.申请权限,3.接收权限处理结果,步数不多,但是代码还是不少。
Easypermissions的使用也是三部,1.检查运行时权限,2.申请权限,3.接收权限处理结果,但是代码比较简洁,便于阅读。
先配置一下,在github上找到这个开源库:
在项目的gradle中添加代码,引用库:
dependencies {
compile 'pub.devrel:easypermissions:0.3.0'
}
版本0.3.0是我现在的最新的库版本。
在需要用到Easypermissions的Activity或者fragment实现接口EasyPermissions.PermissionCallbacks:
public class EasypermissionsTest extends AppCompatActivity implements View.OnClickListener, EasyPermissions.PermissionCallbacks {
并且实现接口中的两个方法:onPermissionsGranted()和onPermissionsDenied()
下面就要进入三部曲了:
String[] permissions = {Manifest.permission.CALL_PHONE};
//1.检查权限
if (EasyPermissions.hasPermissions(this, permissions)) {
call();
Log.e("onClick", "call");
} else {
//如果没有权限,申请权限
//第二个参数是被拒绝后再次申请该权限的解释
//第三个参数是请求码
//第四个参数是要申请的权限
EasyPermissions.requestPermissions(this, "打电话的权限", 1, permissions);
}
3.把申请的权限交给EasyPermissions处理:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//把申请权限的回调交由EasyPermissions处理
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
然后在接口的两个方法里进行处理,onPermissionsGranted是授权成功的方法,onPermissionsDenied是拒绝的方法:
//下面两个方法是实现EasyPermissions的EasyPermissions.PermissionCallbacks接口
//分别返回授权成功和失败的权限
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
switch (requestCode) {
case 1:
call();
Log.e("EasypermissionsTest", "call");
break;
}
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
switch (requestCode) {
case 1:
Toast.makeText(this, "You denied the call permission", Toast.LENGTH_SHORT).show();
break;
}
}
over