如何解决使用React Native FS将文件写入Android外部存储
我的React Native Android应用程序需要将JSON文件保存在外部存储中的特殊文件夹中。我正在尝试通过RNFS(https://github.com/itinance/react-native-fs)来做到这一点:
const saveData = async () => {
var path = `${RNFS.ExternalStorageDirectoryPath}/MyApp`;
RNFS.mkdir(path);
path += '/data.json';
RNFS.writeFile(path,JSON.stringify(getData()),'utf8')
.then((success) => {
console.log('Success');
})
.catch((err) => {
console.log(err.message);
});
}
它运行良好,但在Android Q设备上无法运行。显示此错误:
Error: Directory Could not be created
ENOENT: open Failed: ENOENT (No such file or directory),open '/storage/emulated/0/data.json'
但是,我已经将此权限添加到了AndroidManifest.xml
:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
并在设置中授予了外部存储权限。但是,如果我将RNFS.ExternalStorageDirectoryPath
更改为RNFS.DocumentDirectoryPath
,它将可以正常工作。但是我需要访问外部存储。有什么办法吗?
解决方法
我发现Android API 29+需要旧版外部存储访问权限。因此,我像这样编辑了AndroidManifest.xml
(位于android/app/src/main/
中):
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.appName">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
...
android:requestLegacyExternalStorage="true"
...
>
</application>
</manifest>
一切都开始起作用。另外,我还添加了一个向saveData
函数授予权限的请求:
const saveData = async () => {
try {
const granted = await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,]);
} catch (err) {
console.warn(err);
}
const readGranted = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
const writeGranted = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);
if(!readGranted || !writeGranted) {
console.log('Read and write permissions have not been granted');
return;
}
var path = `${RNFS.ExternalStorageDirectoryPath}/MyApp`;
RNFS.mkdir(path);
path += '/data.json';
RNFS.writeFile(path,JSON.stringify(getData()),'utf8')
.then((success) => {
console.log('Success');
})
.catch((err) => {
console.log(err.message);
});
}
,
在Android版本10(API级别29)中,引入了范围存储的概念。 根据Docs-
“使用户可以更好地控制其文件并限制文件 杂乱无章,针对Android 10(API级别29)及更高版本的应用 通过以下方式获得对外部存储或范围存储的范围内访问: 默认。此类应用只能访问以下位置的应用特定目录: 外部存储以及该应用具有的特定媒体类型 已创建。”
对于Android版本10,您可以选择通过以下方式退出作用域存储
加
AndroidManifest.xml中的android:requestLegacyExternalStorage="true"
这是一个临时解决方案,仅适用于android版本10及其更高版本。 另外,请确保您要求运行时权限来读取/写入外部存储。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。