在android6.0中需要对危险权限进行动态申请,否则,在用到相关权限而并没有开启时,会出现Crash。
官方列出的危险权限如下:
此处演示以fragment中请求定位为例:
private static final int REQUEST_LOCATION_CODE = 88;
//判断是否打开了权限
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//判断系统版本是否不小于6.0
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//android6.0以下shouldShowRequestPermissionRationale方法一直为false
if (!shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
AlertDialog dialog = new AlertDialog.Builder(activity)
.setMessage("请在应用权限中打开定位权限,否则部分功能将无法使用!")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.create();
dialog.setCancelable(true);
dialog.show();
}
}
//请求定位权限,当用户选择以后不再提醒后,不能再调起该询问对话框
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_CODE);
} else {
//启动定位
if (mLocationClient != null) {
mLocationClient.startLocation();
}
}
根据自定义的回调码,可以在activity的onRequestPermissionsResult方法中分别执行权限通过和权限拒绝的回调:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == REQUEST_LOCATION_CODE){
LogUtil.getInstance().error("权限申请结果:"+grantResults[0]);
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
//权限通过
if (mLocationClient != null) {
mLocationClient.startLocation();
}
}else{
//权限拒绝
//提示,或执行权限拒绝时的页面展示
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
此处注意:
在Fragment中申请权限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否则会回调到Activity的 onRequestPermissionsResult。如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方 法,onRequestPermissionsResult不会回调回来,可以使用 getParentFragment().requestPermissions方法,在父Fragment的回调方法中,找到对应子fragment,调用对应方法即可。