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

React Native 0.60.4升级SDK至29后Android10文件下载路径失效求助

解决方案与替代库推荐

Hey there, I’ve run into similar headaches with rn-fetch-blob after upgrading to target SDK 29 on Android 10, so let’s break down how to fix this or switch to a more reliable alternative.

先尝试修复 rn-fetch-blob 的问题

Even with android:requestLegacyExternalStorage="true" added, there are a few key checks to make:

  • Double-check your AndroidManifest.xml setup
    Ensure the permission and legacy flag are placed correctly (don’t miss wrapping the flag inside the <application> tag):

    <manifest ...>
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      <application
        ...
        android:requestLegacyExternalStorage="true">
        ...
      </application>
    </manifest>
    

    Note: This flag works only for SDK 29; it gets ignored for SDK 30+, but since you’re targeting 29, it should still help bypass scoped storage restrictions temporarily.

  • Avoid hardcoded paths
    Instead of using storage/emulated/0/test, leverage rn-fetch-blob’s built-in directory constants to ensure compatibility:

    import RNFetchBlob from 'rn-fetch-blob';
    
    // Use public Download directory instead of arbitrary custom path
    const downloadPath = `${RNFetchBlob.fs.dirs.DownloadDir}/test`;
    

    Hardcoded paths often fail on Android 10+ even with legacy mode, as scoped storage restricts direct access to arbitrary locations.

  • Update rn-fetch-blob to its latest compatible version
    Older versions of the library don’t handle SDK 29 properly. While rn-fetch-blob is no longer actively maintained, checking for the final updates might resolve the immediate issue.

推荐支持 DownloadManager 与通知功能的替代库

Since rn-fetch-blob is deprecated, switching to a maintained library is a better long-term fix. Here are my top picks:

1. react-native-fs

This is a widely adopted, well-maintained library that natively supports Android’s DownloadManager with progress notifications out of the box.

Basic download example with notification:

import RNFS from 'react-native-fs';

const downloadFile = async () => {
  const url = 'https://example.com/your-file.pdf';
  const downloadDest = `${RNFS.DownloadDirectoryPath}/test/your-file.pdf`;

  const options = {
    fromUrl: url,
    toFile: downloadDest,
    background: true, // Enable background download
    progressDivider: 1, // Update progress every 1%
    notification: {
      title: 'Downloading File',
      description: 'Please wait...',
      autoClear: true,
      color: '#2196F3'
    }
  };

  try {
    const jobId = await RNFS.downloadFile(options).promise;
    console.log('Download finished:', jobId);
  } catch (error) {
    console.error('Download failed:', error);
  }
};

2. react-native-download-manager

A lightweight, focused library built directly around Android’s DownloadManager, with straightforward notification configuration and background download support.

Example usage:

import DownloadManager from 'react-native-download-manager';
import RNFS from 'react-native-fs';

DownloadManager.download({
  url: 'https://example.com/your-file.pdf',
  title: 'My Download',
  description: 'In progress...',
  destination: `${RNFS.DownloadDirectoryPath}/test/your-file.pdf`,
  showNotification: true,
  notificationVisibility: DownloadManager.VISIBILITY_VISIBLE_NOTIFY_COMPLETED
});

3. expo-file-system (works for bare React Native apps too)

If you’re open to using Expo libraries in your bare project, expo-file-system offers robust download capabilities. You can pair it with expo-notifications to add custom progress alerts.

Download example with progress tracking:

import * as FileSystem from 'expo-file-system';

const downloadFile = async () => {
  const url = 'https://example.com/your-file.pdf';
  const downloadDest = `${FileSystem.documentDirectory}test/your-file.pdf`;

  const downloadResumable = FileSystem.createDownloadResumable(
    url,
    downloadDest,
    {},
    (progress) => {
      const percent = (progress.totalBytesWritten / progress.totalBytesExpectedToWrite) * 100;
      console.log(`Progress: ${Math.round(percent)}%`);
      // Use expo-notifications to update a custom notification here
    }
  );

  try {
    const { uri } = await downloadResumable.downloadAsync();
    console.log('File saved to:', uri);
  } catch (error) {
    console.error('Download failed:', error);
  }
};

Final Tips

For Android 10+, even with legacy storage enabled, stick to public directories like Download or app-specific storage instead of arbitrary custom paths. This will help your app comply with scoped storage rules and avoid issues when upgrading to SDK 30+.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:25:16