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
相关产品推荐
相关产品推荐

