Android权限系统源于Android是沙盒应用,系统为每个应用分配一个独一无二的linux用户id,因此每个应用是独立且受限的。
Android 5.1及以前
- AndroidManifest.xml声明所需要的权限即可,必须全部同意才能安装。
- 系统设置里没有关掉应用某个权限的功能,也就是除了卸载无法撤回权限。
Android 6.0以后
权限分类
- 普通权限,只需要在Manifest申请即可。
- 危险权限,不仅需要在manifest申明,还需要动态申请。
- 特殊权限,无法动态申请,只能去系统设置打开。目前有两个,修改系统设置和悬浮窗。
注:6.0指的是设备系统6.0以上且targetSdkVersion >= 23。
权限组
权限的检查与授权是以权限组为单位的,同一个权限组的任意一个权限被同意了,同组下的其它权限也有了。
例如READ_CALENDAR和WRITE_CALENDAR都属于CALENDAR组,申请READ_CALENDAR时是申请整组CALENDAR权限,通过以后如果再request WRITE_CALENDAR时直接授权。
事实上都不需要再request,check的时候就是true。
具体权限分组查看权限分组。
危险权限的获取
危险权限的使用需要先判断是否有权限,没有弹框获取,这个弹框界面不能自定义。
如果用户勾选过不再提示或者系统本身禁用该权限将无法弹出申请权限对话框。
private void checkPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
// 没有权限,需要申请
if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {
// 用户之前勾选过不再提示,无法弹出申请权限对话框,建议引导到系统设置打开权限。
return;
}
// 弹出申请权限对话框,建议申请前弹框解释一下为什么需要权限
ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode);
} else {
// 有权限
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_READ_CALENDAR) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 获取到权限
} else {
// 被拒绝
}
}
}
注:fragment直接调用自己的requestPermissions不要调用ContextCompat.checkSelfPermission,否则走不到自己的onRequestPermissionsResult()。
特殊权限的获取
特殊权限目前只有修改系统设置和悬浮窗两个。
通过Settings来判断是否有相关权限,并且只能跳转到设置界面去获取,通过onActivityResult来获取结果。
以悬浮窗为例:
private void requestWriteSettings() {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
if (Settings.System.canWrite(this)) {
// 获取到权限
}
}
}
网友评论