动态获取权限参考文章
1. 授权权限
- 如果设备运行的是Android 6(API Level 23)或更高,和应用程序的targetSdkVersion是23或更高,应用程序要求的权限由用户在运行时。用户可以在任何时间撤销权限,所以在每次运行时应用程序需要检查是否有权限。如果设备运行的是Android 5.1(API Level 22)或更低,或应用程序targetSdkVersion等于或低于22时,当用户安装的应用程序,系统会要求用户授予权限。用户的应用程序更新,如果你添加一个新的权限的应用程序的更新版本,系统会要求用户授予权限时。一旦用户安装该应用程序,他们可以撤销许可的唯一途径是通过卸载应用程序。
2.拒绝权限
- 每当一个权限被拒绝应向用户解释使用该权限的具体用途,保证功能要求的权限总是行为为目的,应用程序应该说是需要许可,允许它提供了一种方法。而权限被拒绝的途径以下两种:
由用户拒绝权限请求
用户选择过“不要再问”,用户权限是默默的否认,没有警告
3. 申请权限
在BaseActivity里写授权申请,首先检查申请的权限是不是被授权了,如果不是就加入待授权数组里,去申请权限。如果全部已授权,就直接回掉授权成功。
public static void checkAndRequestPermission() {
if (Build.VERSION.SDK_INT >= 23) {
List<String> lackedPermission = new ArrayList<String>();
if (!(mActivity.checkSelfPermission(Manifest.permission.READ_PHONE_STATE)== PackageManager.PERMISSION_GRANTED)) {
lackedPermission.add(Manifest.permission.READ_PHONE_STATE);
}
if (!(mActivity.checkSelfPermission(Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) == PackageManager.PERMISSION_GRANTED)) {
lackedPermission.add(Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
}
// 权限都已经有了,那么直接调用SDK
if (lackedPermission.size() == 0) {
} else {
// 请求所缺少的权限,在onRequestPermissionsResult中再看是否获得权限,如果获得权限就可以调用SDK,否则不要调用SDK。
String[] requestPermissions = new String[lackedPermission.size()];
lackedPermission.toArray(requestPermissions);
mActivity.requestPermissions(requestPermissions, 101);
}
}
}
然后重写授权返回方法。系统会返回2个数组, String[] permissions是你申请的权限,int[] grantResults是授权结果。拿出授权结果比对,如果授权,加入授权数组,如果拒绝,加入拒绝数组。回掉给注册PermissionListener的activity
/** 申请结果
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if (grantResults.length>0){
List<String> deniedPermissions = new ArrayList<>();
List<String> grantedPermissions = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
if (grantResult != PackageManager.PERMISSION_GRANTED){
String permission = permissions[i];
deniedPermissions.add(permission);
}else{
String permission = permissions[i];
grantedPermissions.add(permission);
}
}
if (deniedPermissions.isEmpty()){
mPermissionListener.onGranted();
}else{
mPermissionListener.onDenied(deniedPermissions);
mPermissionListener.onGranted(grantedPermissions);
}
}
break;
}
}
4. Android 10 无法读取本地文件 FileNotFoundException: Permission denied 解决办法
- 本来动态获取权限很顺利,设置里也能看到获取了权限,但是本地访问文件没有权限,才发现是android 10 的问题。这里有官方说明: Android 10 管理分区外部存储访问
解决办法:
- 在Mainfest Application中加入这一行 android:requestLegacyExternalStorage="true", 如下:
<application
android:label="@string/app_name"
android:allowBackup="true"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:icon="@mipmap/ic_launcher">
...
</application>