一、前言:
首先,来讲一讲运行时权限。从Android 6.0开始,Google引入了运行时权限。Android中的权限分为两类:Normal Permission和Dangerous Permission。Normal Permission(即普通权限,一般不涉及到用户隐私),比如访问网络、手机震动等等;Dangerous Permission(一般涉及到用户隐私),比如读取sdcard、拨打电话、访问通讯录等等。
从Android 6.0开始,对于Dangerous Permission,是需要用户授权的,仅仅在AndroidManifest中声明权限是不管用的。
二、相关API:
1、ContextCompat.checkSelfPermission(Context context, String permission)
主要用来检测某个权限是否已经被授权
方法的返回值为PackageManager.PERMISSION_GRANTED或者PackageManager.PERMISSION_DENIED
当返回值为PackageManager.PERMISSION_DENIED就需要进行申请授权了。
2、ActivityCompat.requestPermissions(Activity activity, String[] permissions, int requestCode)
申请授权
第一个参数是Activity实例
第二个参数是需要申请的权限的字符串数组
第三个参数是requestCode,主要用于回调的时候检测
该方法是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权
3、onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults)
处理权限申请回调
4、ActivityCompat.shouldShowRequestPermissionRationale(Activity activity, String permission)
这个API主要用于给用户一个申请权限的解释
三、例子:
我们拿拨打电话举例。
1、在AndroidManifest.xml中声明权限:
<uses-permission android:name="android.permission.CALL_PHONE" />
2、
public void testCall(Context context, String phoneNumber) {
/**
* 这里要处理一个“允许拨打电话”的运行时权限
* ContextCompat.checkSelfPermission,主要用来检测某个权限是否已经被授权,
* 方法返回值为PackageManager.PERMISSION_GRANTED或者PackageManager.PERMISSION_DENIED
* 当返回DENIED就需要进行申请授权了
*/
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
/**
* ActivityCompat.shouldShowRequestPermissionRationale
* 这个API主要用于给用户一个申请权限的解释
*/
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)) {
Toast.makeText(this, "您需要此权限来拨打电话", Toast.LENGTH_SHORT).show();
}
/**
* 申请授权
* ActivityCompat.requestPermissions
* 第一个参数是Activity实例
* 第二个参数是需要申请的权限的字符串数组
* 第三个参数是requestCode,主要用于回调的时候检测
*
* 该方法是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权
*/
ActivityCompat.requestPermissions(this,
new String[] {Manifest.permission.CALL_PHONE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
} else {
call(context, phoneNumber);
}
}
/**
* 处理权限申请回调
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_CALL_PHONE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
call(this, "10086");
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
/**
* 拨打电话
* @param context 上下文对象
* @param phoneNumber 电话号码
*/
public void call(Context context, String phoneNumber) {
context.startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber)));
}