微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用React Native FS将文件写入Android外部存储

如何解决使用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 举报,一经查实,本站将立刻删除。