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

React Native安卓端:下载前调用文件管理器选目录的实现方法

实现安卓文件管理器选择目录并保存Base64文件(rn-fetch-blob)

核心思路

rn-fetch-blob本身不提供目录选择UI,需要结合安卓原生Intent或第三方文件选择库唤起系统文件管理器,获取用户选中的目录路径后,再用writeFile写入Base64内容。以下提供两种可行方案:


方案一:纯rn-fetch-blob实现(无额外依赖)

直接调用安卓原生Intent唤起文件管理器,无需安装第三方库:

1. 配置权限

在android/app/src/main/AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 适配安卓10+的存储权限 -->
<application
  ...
  android:requestLegacyExternalStorage="true">
  ...
</application>

2. 代码实现

import RNFetchBlob from 'rn-fetch-blob';

// 唤起文件管理器选择目录
const pickDirectory = () => {
  return new Promise((resolve, reject) => {
    // 调用安卓的OPEN_DOCUMENT_TREE Intent
    RNFetchBlob.android.actionIntent(
      'android.intent.action.OPEN_DOCUMENT_TREE',
      [],
      (result) => {
        if (result.code === 'RESULT_OK') {
          // 将Content URI转换为真实文件路径
          RNFetchBlob.android.getRealPathFromURI(result.data)
            .then(resolve)
            .catch(reject);
        } else {
          reject(new Error('用户取消目录选择'));
        }
      }
    );
  });
};

// 动态申请存储权限
const checkStoragePermission = async () => {
  const permissions = await RNFetchBlob.android.permissions.request([
    RNFetchBlob.android.permissions.READ_EXTERNAL_STORAGE,
    RNFetchBlob.android.permissions.WRITE_EXTERNAL_STORAGE,
  ]);
  return permissions[RNFetchBlob.android.permissions.WRITE_EXTERNAL_STORAGE] === 'granted';
};

// 保存Base64文件到选中目录
const saveBase64ToSelectedDir = async (base64Content, fileName) => {
  // 先检查权限
  const hasPermission = await checkStoragePermission();
  if (!hasPermission) {
    alert('请授予存储权限以保存文件');
    return;
  }

  try {
    const targetDir = await pickDirectory();
    if (!targetDir) return;

    const fullPath = `${targetDir}/${fileName}`;
    // 写入Base64内容,指定编码为'base64'
    await RNFetchBlob.fs.writeFile(fullPath, base64Content, 'base64');
    alert(`文件已保存至:${fullPath}`);
  } catch (err) {
    console.error('保存失败:', err);
    alert('文件保存失败,请重试');
  }
};

// 调用示例
// saveBase64ToSelectedDir('你的Base64字符串', 'test.pdf');

方案二:使用第三方库(更简洁)

如果觉得原生Intent实现繁琐,可以用react-native-document-picker(轻量且维护活跃):

1. 安装依赖

npm install react-native-document-picker
# 或 yarn add react-native-document-picker

2. 代码实现

import RNFetchBlob from 'rn-fetch-blob';
import DocumentPicker from 'react-native-document-picker';

const saveBase64WithPicker = async (base64Content, fileName) => {
  const hasPermission = await checkStoragePermission(); // 复用方案一中的权限检查函数
  if (!hasPermission) return;

  try {
    // 唤起目录选择器
    const result = await DocumentPicker.pick({
      type: [DocumentPicker.types.allFiles],
      allowDirectory: true, // 关键:允许选择目录
      mode: 'open',
    });

    // 转换为真实路径
    const targetDir = await RNFetchBlob.android.getRealPathFromURI(result.uri);
    const fullPath = `${targetDir}/${fileName}`;

    await RNFetchBlob.fs.writeFile(fullPath, base64Content, 'base64');
    alert('文件保存成功');
  } catch (err) {
    if (DocumentPicker.isCancel(err)) {
      console.log('用户取消选择');
    } else {
      console.error('保存失败:', err);
      alert('文件保存失败');
    }
  }
};

注意事项

  • 安卓11+适配:若requestLegacyExternalStorage失效,可直接使用DocumentPicker返回的Content URI,配合rn-fetch-blob的fs.writeFile(部分场景下无需转真实路径)。
  • 文件命名:确保文件名包含正确后缀(如.pdf、.png),避免系统无法识别文件类型。
  • 错误处理:需捕获权限拒绝、用户取消、路径不存在等异常场景。

内容的提问来源于stack exchange,提问作者Rino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:05:21