Android6.0新特性,运行时权限。以打电话为例。
步骤:
1、检查权限:有就打电话;没有就请求权限(如果之前用户拒绝过,先提示为啥需要这个权限)。
2、请求权限回来后:如果成功就打电话;没成功就提示被拒绝(如果勾选了“不再询问”则提示如何手动打开权限)。
代码如下:
private void call() {
//检查权限
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
//没有就去申请
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CALL_PHONE)) {
// 用户拒绝过这个权限了,应该提示用户,为什么需要这个权限。
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setMessage("解释一下,因为你要打电话,所以需要打电话权限。")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
//继续请求权限
requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, PERMISSIOINS_REQUEST_CODE_CALL);
}
}).create();
dialog.show();
}else {
//请求权限,fragment中运行时权限的特殊处理、在Fragment中申请权限、不要使用ActivityCompat.requestPermissions、直接使用Fragment的requestPermissions方法、否则会回调到Activity的 onRequestPermissionsResult
requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, PERMISSIOINS_REQUEST_CODE_CALL);
}
} else {
callPhone();
}
}
/**
* 申请权限的回调
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSIOINS_REQUEST_CODE_CALL) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
callPhone();
}
//拒绝后,再次弹框提示申请权限 ,若勾选“不再询问”后点击拒绝,会走此逻辑(此时shouldShowRequestPermissionRationale返回false)。
//因为已经拒绝且不在提示,需要告诉用户如何打开权限。
else if (!ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CALL_PHONE)) {
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setMessage("该功能需要访问电话的权限,当前未打开权限! 打开权限的方法:设置-应用—权限。")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create();
dialog.show();
} else {
Toast.makeText(getContext(), "被拒绝了", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 打电话.
* <p>
* 注意:
* android.intent.action.CALL需要在配置文件中添加拨号权限 且 点击后直接拨号
* android.intent.action.DIAL只是调用拨号键盘,不用在文件中添加权限
*/
private void callPhone() {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + "10086"));
startActivity(intent);
}
效果图
1、第一次申请权限,用户拒绝了,再次申请时 提示用户为啥需要这个权限,以免用户勾选“不再询问”且拒绝。
2、点击确定后,申请权限的弹框 会有“不在询问”的勾选框
3、勾选“不再询问”后拒绝 的提示,告诉用户怎么打开权限。
比较好的文章及框架:
目前最流行的运行时权限请求框架PermissionsDispatcher、RxPermissions和easypermissions的使用和对比