背景:Android6.0以前申请权限只需要在配置清单文件中申请,安装时全部授予,运行时不在询问用户。6.0及之后部分涉及到用户隐私安全方面的权限需要在运行时去动态询问用户是否授予该权限。
正常权限和危险权限
正常权限涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。如需当前正常权限的完整列表,请参阅正常权限。
危险权限涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域 。
权限组(所有危险的 Android 系统权限都属于权限组)
如果应用请求其清单中列出的危险权限,而应用目前在权限组中没有任何权限,则系统会向用户显示一个对话框,描述应用要访问的权限组。
如果应用请求其清单中列出的危险权限,而应用在同一权限组中已有另一项危险权限,则系统会立即授予该权限,而无需与用户进行任何交互。
危险权限和权限组
权限组 | 权限 |
---|---|
CALENDAR | |
CAMERA | |
CONTACTS | |
LOCATION | |
MICROPHONE | |
PHONE | |
SENSORS | |
SMS | |
STORAGE |
- 检查权限
/** * @param permission 所检测的权限,如:Manifest.permission.WRITE_CALENDAR * @return true具有此权限,false不具有此权限 */ public boolean checkPermission(String permission) { int permissionCheck = ContextCompat.checkSelfPermission(this,permission); //如果应用具有此权限,方法将返回 PackageManager.PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具有此权限, // 方法将返回 PERMISSION_DENIED,且应用必须明确向用户要求权限。 return permissionCheck == PackageManager.PERMISSION_GRANTED ? true : false; }
请求权限
/** * @param permission */ public void requestPermission(String permission) { if (!checkPermission(permission)) {//先检测是否授予了该权限 if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {//如果应用之前请求过此权限但用户拒绝了请求,此方法将返回true. // 如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回 false。 // 如果设备规范禁止应用具有该权限,此方法也会返回 false。 //最好解释应用为什么需要权限 } else//请求权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_READ_CONTACTS); } }
权限请求响应
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_READ_CONTACTS: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//用户授予权限 } else {//用户禁止权限,您的应用应采取适当的操作。例如,您的应用可能显示一个对话框,解释它为什么无法执行用户已经请求但需要该权限的操作。 } return; } super.onRequestPermissionsResult(requestCode, permissions, grantResults); }
参考地址:https://developer.android.google.cn/training/permissions/requesting.html#perm-request