一、前言
在开发中用到了SD卡的存储,在AndroidManifest.xml里开启后并不起作用。在执行需要权限的代码时就会出现:IOException: No such file or directory 这样的错误。
原因是在API23(Android6.0之后),有一些危险权限只能动态获取,如定位、电话、麦克风等。
查到了解决办法,现记录一下。
二、动态获取权限
动态获取权限是API23以后开始要求的,也就是我们目前使用APP底部弹出的获取权限的选项。
动态获取需要两步:
STEP1:配置静态权限
在AndroidManifest.xml中添加以下权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
STEP2:动态获取权限
在MainActivity.java的启动位置或者需要的地方检查并动态获取权限
String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
List<String> mPermissionList = new ArrayList<>();
// private ImageView welcomeImg = null;
private static final int PERMISSION_REQUEST = 1;
// 检查权限
private void checkPermission() {
mPermissionList.clear();
//判断哪些权限未授予
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permissions[i]);
}
}
/**
* 判断是否为空
*/
if (mPermissionList.isEmpty()) {//未授予的权限为空,表示都授予了
} else {//请求权限方法
String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组
ActivityCompat.requestPermissions(MainActivity.this, permissions, PERMISSION_REQUEST);
}
}
/**
* 响应授权
* 这里不管用户是否拒绝,都进入首页,不再重复申请权限
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSION_REQUEST:
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
使用示例:
@Override
protected void onCreate(Bundle savedInstanceState){
checkPermission();
super.onCreate(savedInstanceState);
}
这样就动态的获取到了存储权限,看下效果图(这里程序程序不是我写的,我只是在此基础上加了动态获取权限):
三、举一反三
这样动态的获取到了存储权限,那么对于其它的存储权限需要动态获取的话也就是同样的道理。
在前面提到的代码中修改权限名称即可,
String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
在这里加上需要动态获取的权限名即可
附上危险权限列表及其名称:
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
四、参考资料:
链接: