文件读写异常
1.除了没有授予读写权限
2.除了文件路劲异常
java.io.FileNotFoundException:
/storage/emulated/0/Image/1684917871626.png: open failed: EPERM
(Operation not permitted)
android 10(Q)开始增加了沙盒机制,不能直接把文件保存到/sdcard目录下,只能保存到APP专属目录下;AndroidManifest.xml在标签下增加属性【android:requestLegacyExternalStorage=“true”】可以暂时保存到/sdcard路径下
但是在目标版本在Android 11及以上 在/sdcard下的读写就不生效了 , 报open failed: EPERM
(Operation not permitted) 错误
追寻原因 发现在 Android 11中 File.mkdirs() 一直是false,就连文件夹都创建不了 更别提文件操作。
最后查找到原因: 由于Android 11范围的存储被强制执行。针对Android 10(API级别29)的应用程序仍然可以请求requestLegacyExternalStorage属性。此标志允许应用程序暂时退出与作用域存储相关的更改,例如授予对不同目录和不同类型媒体文件的访问权限。将应用程序更新为目标Android 11后,系统将忽略requestLegacyExternalStorage标志。
在 API 级别 29 中,不推荐直接访问共享/外部存储设备。当应用定位到Build.VERSION_CODES时。Q,从getExternalStorageDirectory()方法返回的路径不再可直接被应用程序访问。应用可以通过迁移到 Context#getExternalFilesDir(String)、MediaStore 或 Intent#ACTION_OPEN_DOCUMENT 等替代项来继续访问存储在共享/外部存储上的内容。
最终的解决方案:在 API 级别 30 Android11 及以上 不要在 /sdcard 外部路劲下存储资源 ,使用内部存储路劲操作资源。
private String getSavePath() {
String path;
if (Build.VERSION.SDK_INT > 29) {
path = mContext.getExternalFilesDir(null).getAbsolutePath() + "/app/audio/";
} else {
path = Environment.getExternalStorageDirectory().getPath() + "/app/audio/";
}
return path;
}
这样就可以在不报错的情况下 做文件存储,
但是高版本保存图片.视频 在内部存储下 没法直接共享于手机相册中————