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

RN Fetch Blob在Android 14上异常:应用崩溃且文件无法打开

问题解决:React Native 0.73 + Android 14 下 RNFetchBlob 下载崩溃与文件无法打开

一、崩溃问题(receiver_exported/receiver_not_exported 报错)

Android 14(API 34)强制要求所有广播接收器必须显式声明android:exported属性,RNFetchBlob 旧版本未适配该规则,导致下载完成后触发广播时崩溃。

解决方法:

  1. 升级 RNFetchBlob 到最新适配版本
    执行升级命令:

    npm install rn-fetch-blob@latest
    # 或 yarn add rn-fetch-blob@latest
    
  2. 手动修改 AndroidManifest.xml
    如果暂时无法升级,在项目的android/app/src/main/AndroidManifest.xml中添加广播接收器的exported属性:

    <receiver
        android:name="com.RNFetchBlob.RNFetchBlobDownloadCompleteReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
        </intent-filter>
    </receiver>
    

    注:若接收器需接收系统全局广播,设为android:exported="true",否则设为false即可。

二、文件无法打开(提示“Can't open file”)

该问题通常由权限不足、MIME类型未指定或文件路径访问限制导致,可按以下步骤修复:

解决方法:

  1. 添加 MIME 类型配置
    在addAndroidDownloads配置中指定文件的MIME类型,让系统识别文件格式:

    addAndroidDownloads: {
      useDownloadManager: true,
      notification: true,
      path: `${dirToSave}/ows-booking-invoice-${invoiceResponse.variables?.orderId}.pdf`,
      mime: 'application/pdf', // 新增PDF的MIME类型
      mediaScannable: true, // 让系统媒体库扫描到该文件
    }
    
  2. 检查文件权限与路径

    • Android 10+ 访问公共下载目录(DownloadDir)无需申请WRITE_EXTERNAL_STORAGE权限,但需确保路径正确,mediaScannable: true可触发系统扫描更新文件索引。
    • 若仍无法访问,可尝试切换到应用私有目录:
      android: RNFetchBlob.fs.dirs.CacheDir // 或 RNFetchBlob.fs.dirs.DCIMDir
      
  3. 优化文件打开逻辑
    Android下打开文件需确保路径被系统认可,可修改下载完成后的打开逻辑:

    } else {
      console.log("File downloaded ");
      // 直接调用系统应用打开PDF
      RNFetchBlob.android.actionViewIntent(
        res.path(),
        'application/pdf'
      );
      Snackbar.show({
        text: 'File Downloaded.',
        duration: Snackbar.LENGTH_SHORT,
      });
    }
    

完整修改后的代码示例

useEffect(() => {
  setIsInvoiceDownloading(true);
  if (invoiceResponse.error && invoiceResponse.called) {
    console.log("Error in invoiceResponse")
    setIsInvoiceDownloading(false);
    firebase
      .analytics()
      .logEvent('ApiErrorMessage', { API: 'INVOICE_DOWNLOAD' });
    Snackbar.show({
      text: 'Could not fetch invoice. Please try again.',
      duration: Snackbar.LENGTH_SHORT,
    });
  } else if (invoiceResponse.data) {
    console.log("Success in invoiceResponse ", invoiceResponse)
    const dirToSave = Platform.select({
      ios: RNFetchBlob.fs.dirs.DocumentDir,
      android: RNFetchBlob.fs.dirs.DownloadDir,
    });
    console.log("dirToSave invoiceResponse", dirToSave);
    RNFetchBlob.config({
      fileCache: true,
      path: `${dirToSave}/ows-booking-invoice-${invoiceResponse.variables?.orderId}.pdf`,
      addAndroidDownloads: {
        useDownloadManager: true,
        notification: true,
        path: `${dirToSave}/ows-booking-invoice-${invoiceResponse.variables?.orderId}.pdf`,
        mime: 'application/pdf',
        mediaScannable: true,
      },
    })
      .fetch('GET', invoiceResponse.data.getInvoicePdfByBookingId)
      .then((res) => {
        console.log("Fetch successful, response ", res);
        setIsInvoiceDownloading(false);
        if (Platform.OS === 'ios') {
          RNFetchBlob.ios.openDocument(res.data);
        } else {
          console.log("File downloaded ");
          RNFetchBlob.android.actionViewIntent(res.path(), 'application/pdf');
          Snackbar.show({
            text: 'File Downloaded.',
            duration: Snackbar.LENGTH_SHORT,
          });
        }
      })
      .catch((err) => {
        console.log("Fetch failed, error: ", err);
        firebase
          .analytics()
          .logEvent('ApiErrorMessage', { API: 'INVOICE_DOWNLOAD' });
        setIsInvoiceDownloading(false);
        Snackbar.show({
          text: 'Could not download invoice. Please try again.',
          duration: Snackbar.LENGTH_SHORT,
        });
      });
  }
}, [invoiceResponse]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:26:04