uni-app Android10设备已有外部存储权限 操作文件依然出现targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径
uni-app Android10设备已有外部存储权限 操作文件依然出现targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径
信息类别 | 详细信息 |
---|---|
产品分类 | uniapp/App |
PC开发环境 | Windows |
PC版本号 | Windows 11, version 23H2 |
HBuilderX类型 | 正式 |
HBuilderX版本 | 4.27 |
手机系统 | Android |
手机版本号 | Android 10 |
手机机型 | PanoX v2 |
页面类型 | vue |
vue版本 | vue2 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
操作步骤:
plus.io.resolveLocalFileSystemURL(
fileUrl, //指定的文件路径 file:///storage/RFE8-RE/DCIM/photo/test
(entry) => {
console.log('entry',entry);
entry.remove(
() => {
console.log('删除文件成功');
},
(err) => {
console.log("删除文件失败",err);
});
},
(err) => {
console.log("访问指定文件失败:",err);
});
```
### 预期结果:
在安卓10设备上有权限删除外部存储文件上正常删除
### 实际结果:
在安卓10上有删除外部存储文件权限时无法删除,提示targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径!具体请看:https://ask.dcloud.net.cn/article/36199
### bug描述:
使用安卓原生方式删除是有权限删除DCIM文件夹里的文件,以及在安卓14设备上获取到所有文件管理权限后使用下面代码是可以正常删除的。但是在安卓10设备上使用下面代码删除文件时报错targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径!具体请看:https://ask.dcloud.net.cn/article/36199
```
plus.io.resolveLocalFileSystemURL(
fileUrl, //指定的文件路径 file:///storage/RFE8-RE/DCIM/photo/test
(entry) => {
console.log('entry',entry);
entry.remove(
() => {
console.log('删除文件成功');
},
(err) => {
console.log("删除文件失败",err);
});
},
(err) => {
console.log("访问指定文件失败:",err);
});
在处理 uni-app
在 Android 10 (API 级别 29) 及以上设备上操作文件的问题时,特别是当 targetSdkVersion
设置为 29 或更高时,由于 Android 系统的存储访问框架(Scoped Storage)变更,传统的文件路径访问方式可能会受到限制。Android 10 引入了分区存储(Scoped Storage),旨在增强用户的隐私保护和数据隔离。
为了解决这个问题,你可以考虑以下几种方法,这里我将提供代码示例来说明如何使用 MediaStore
API 来访问和操作媒体文件,以及如何使用 Storage Access Framework
来访问非媒体文件。
使用 MediaStore API 访问媒体文件
对于图片、视频和音频文件,你可以使用 MediaStore
API 来代替直接的文件路径访问。以下是一个简单的示例,展示如何插入一张图片到 MediaStore
:
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "example.jpg");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/MyApp");
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (uri != null) {
try (OutputStream outputStream = getContentResolver().openOutputStream(uri)) {
// 写入图片数据到outputStream
} catch (IOException e) {
e.printStackTrace();
}
}
使用 Storage Access Framework 访问非媒体文件
对于非媒体文件,如文档或应用特定的数据文件,你可以使用 Storage Access Framework 来请求用户授权访问特定目录。以下是如何启动一个文件选择器让用户选择一个目录:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
在 onActivityResult
中处理用户选择:
if (requestCode == REQUEST_CODE_OPEN_DOCUMENT_TREE && resultCode == RESULT_OK) {
Uri treeUri = data.getData();
// 保存treeUri以便后续访问该目录
getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
结论
由于 Android 10+ 的分区存储限制,直接的文件路径访问方式可能不再适用。因此,推荐使用 MediaStore
API 来处理媒体文件,以及 Storage Access Framework
来处理非媒体文件。这些方法确保了应用兼容最新的 Android 存储访问策略,同时提供了更好的用户体验和数据保护。