You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中使用RNFS(react-native-fs)写入文件权限报错排查

Android中RNFS写入文件权限拒绝问题排查

错误信息

Permission Denial: writing com.android.providers.media.MediaDocumentsProvider uri content://com.android.providers.media.documents/document/image%3A1000004616 from pid=8769, uid=10304 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()

你的代码与配置问题分析

1. RNFS.writeFile参数顺序完全错误

RNFS的writeFile方法签名是:writeFile(path: string, contents: string, encoding?: string),第一个参数是目标文件路径,第二个是要写入的内容。你现在把content URI和本地路径搞反了,而且RNFS本身不支持直接写入Content URI,它操作的是文件系统路径。

2. MANAGE_DOCUMENTS权限无法通过普通应用获取

这个权限是系统级权限,仅开放给系统应用,普通应用即使在Manifest中声明也无法获得授权,错误提示里的这个选项对你的场景无效。

3. 权限申请逻辑存在判断bug

你的权限判断条件中,前几个权限没有添加=== 'granted'校验,导致只要权限存在就会被判定为true,不管实际是否授权。比如result['android.permission.ACCESS_MEDIA_LOCATION']即使返回denied,也会被视为true。

4. Manifest权限标签不完整

READ_MEDIA_AUDIO权限标签未闭合,少了/>,会导致Manifest解析异常。

解决方案

1. 修正RNFS.writeFile调用

如果你要写入到本地路径/storage/emulated/0/Documents/my_app_folder/my_image.jpg,正确写法如下:

// 替换成你的base64图片内容
const base64ImageContent = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAAAAAAD...';

RNFS.writeFile(
  '/storage/emulated/0/Documents/my_app_folder/my_image.jpg',
  base64ImageContent,
  'base64'
)
.then(() => {
  console.log('FILE WRITTEN!');
})
.catch(err => {
  console.log(err.message);
});

2. 修正权限申请逻辑

try {
  PermissionsAndroid.requestMultiple([
    PermissionsAndroid.PERMISSIONS.ACCESS_MEDIA_LOCATION,
    PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
    PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
    PermissionsAndroid.PERMISSIONS.READ_MEDIA_IMAGES,
    PermissionsAndroid.PERMISSIONS.READ_MEDIA_VIDEO,
    PermissionsAndroid.PERMISSIONS.READ_MEDIA_AUDIO,
  ]).then(result => {
    const allGranted = 
      result['android.permission.ACCESS_MEDIA_LOCATION'] === 'granted' &&
      result['android.permission.READ_EXTERNAL_STORAGE'] === 'granted' &&
      result['android.permission.WRITE_EXTERNAL_STORAGE'] === 'granted' &&
      result['android.permission.READ_MEDIA_IMAGES'] === 'granted' &&
      result['android.permission.READ_MEDIA_VIDEO'] === 'granted' &&
      result['android.permission.READ_MEDIA_AUDIO'] === 'granted';

    if (allGranted) {
      console.log('SUCCESS! Permissions Granted!');
    } else {
      const hasNeverAskAgain = 
        result['android.permission.ACCESS_MEDIA_LOCATION'] === 'never_ask_again' ||
        result['android.permission.READ_EXTERNAL_STORAGE'] === 'never_ask_again' ||
        result['android.permission.READ_MEDIA_IMAGES'] === 'never_ask_again' ||
        result['android.permission.READ_MEDIA_VIDEO'] === 'never_ask_again' ||
        result['android.permission.READ_MEDIA_AUDIO'] === 'never_ask_again';

      if (hasNeverAskAgain) {
        console.log('Please Go into Settings -> Applications -> APP_NAME -> Permissions and Allow permissions to continue');
      }
    }
  });
} catch (err) {
  console.warn(err);
}  

3. 修正Manifest配置

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- Android 13+不再需要WRITE_EXTERNAL_STORAGE,添加maxSdkVersion限制 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<!-- MANAGE_DOCUMENTS是系统权限,添加ignore避免编译警告 -->
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

<!-- Android 10适配,开启遗留存储访问 -->
<application
  ...
  android:requestLegacyExternalStorage="true">
  ...
</application>

4. Android 11+适配说明

如果你的应用目标SDK是30+,写入共享媒体目录(比如相册)建议使用Android原生的MediaStore API,RNFS对这类场景的支持有限;若要写入应用私有目录,无需申请任何存储权限。

内容的提问来源于stack exchange,提问作者Program-Me-Rev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:35:14