官方文档中已经有了详细的介绍和使用说明 https://developer.android.google.cn/guide/topics/security/permissions.html#normal-dangerous
下面是我的一些总结:
1、为什么要动态申请权限?
系统权限分为正常权限和危险权限。正常权限可以在清单文件中列出,系统会自动授予这些权限。对于危险权限,如果设备运行版本大于等于Android 6.0(targetSdkVersion>=23),则不仅需要在清单文件中列出,还需要动态请求权限,否则会抛出SecurityException异常。如果设备运行版本小于Android 6.0(targetSdkVersion<23),则只会在安装应用时请求这些权限,用户一旦安装应用,他们撤销权限的唯一方式就是卸载应用。
2、正常权限和危险权限包括哪些呢?
正常权限是指访问基本资源的权限,是对用户隐私或其他应用操作风险小的权限。比如:访问时区、网络、蓝牙等。正常权限列表:https://developer.android.google.cn/guide/topics/permissions/normal-permissions.html
危险权限涉及对用户隐私、存储的数据,或对其他应用的操作产生影响的权限。危险权限分为9组:日历、相机、联系人、定位、录制音频、电话、传感器、短信、存储卡。如果应用请求危险权限,而应用目前在权限组中没有任何权限,则系统会向用户显示一个对话框,描述应用要访问的权限组。如果一组中的一个权限已经申请过了,则这组权限中的其他权限就不用动态申请了,系统会自动授予这个权限。危险权限列表:https://developer.android.google.cn/guide/topics/security/permissions.html#normal-dangerous
3、如何申请权限?
Google官方demo地址:https://github.com/googlesamples/android-RuntimePermissions
以请求拍照的权限为例:
1、在清单文件中添加:
<uses-permission android:name="android.permission.CAMERA"/>
2、拍照前检查是否已授权
public void showCamera(View view) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// 没有授权,要请求授权
requestCameraPermission();
} else {
// 已经授权,可以执行去拍照的逻辑了
showCameraPreview();
}
}
3、请求拍照权限
private void requestCameraPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// 向用户解释是否需要这个权限
// ActivityCompat.shouldShowRequestPermissionRationale这个判断是可选的,不是一定要添加。
// 解释过了之后,再请求权限requestPermissions()
} else {
// 请求拍照权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},0);
}
}
4、获取权限请求的回调结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == 0) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户授权了
showCameraPreview();
} else {
// 用户未授权
}
}
}
注意点:
1、用户授权过的权限,不用再次申请。如果再次申请也不会有弹窗,系统会直接授权。
2、用户拒绝过的权限,再次申请时弹窗中会有“不在询问”的选项,如果用户勾选了“不在询问”然后点了拒绝,则以后申请都不会显示弹窗,系统会直接拒绝授权。如果用户没有选择“不在询问”,则下一次申请时弹窗还会显示。
3、shouldShowRequestPermissionRationale()用来在用户拒绝了权限(没有选择不再询问的拒绝)时,再次请求权限,给用户一个说明。方法的返回值说明: 返回true的情况,如果应用第一次请求此权限时被用户拒绝了,则之后调用该方法会返回true。返回false的情况,第一次请求权限返回false。第一请求被拒绝了,第二次请求时,用户勾选了“不在询问”时会返回false。