React Native:单击按钮即可使用 rn-fetch-blob 下载 pdf 文件

问题描述 投票:0回答:3

我必须让用户在按下按钮时下载 pdf 文件,我发现我必须使用 rn-fetch-blob 而不是 react-native-fetch-blob。文档中有这样的代码:

const { config, fs } = RNFetchBlob
let DownloadDir = fs.dirs.DownloadDir // this is the Downloads directory.
let options = {
fileCache: true,
addAndroidDownloads : {
useDownloadManager : true, //uses the device's native download manager.
notification : true,
title : "Notification Title", // Title of download notification.
path: DownloadDir + "/me_"+ '.' + extension, // this is the path where your download file will be in
description : 'Downloading file.'
}
}
config(options)
.fetch('GET',"https://whatever_url_u _want/)
.then((res) => {
//console.log("Success");
})
.catch((err) => {console.log('error')}) // To execute when download cancelled and other errors
}

我不知道我能用这个做什么!如何在 TouchableOpacity onPress prop 中使用它?请有人可以提供详细的例子

PS。我使用 POST 方法调用 API,并收到 PDF 文件的链接。我认为

I have to set this link like that
    config(options)
    .fetch('GET',this.state.data.link)
react-native react-native-fetch-blob
3个回答
19
投票
  1. AndroidManifest.xml
  2. 添加以下权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
  1. 要使用downloadmanager,请在AndroidManifest.xml
  2. 中的intent中添加以下操作
<intent-filter>
     <action android:name="android.intent.action.MAIN" />
     <category android:name="android.intent.category.LAUNCHER" />
     <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>                          
</intent-filter>
  1. 从 React Native 导入 PermissionsAndroid、Alert(仅限 Android)
import {PermissionsAndroid, Alert} from "react-native";
  1. 现在在组件中
actualDownload = () => {
   const { dirs } = RNFetchBlob.fs;
  RNFetchBlob.config({
    fileCache: true,
    addAndroidDownloads: {
    useDownloadManager: true,
    notification: true,
    mediaScannable: true,
    title: `test.pdf`,
    path: `${dirs.DownloadDir}/test.pdf`,
    },
  })
    .fetch('GET', 'http://www.africau.edu/images/default/sample.pdf', {})
    .then((res) => {
      console.log('The file saved to ', res.path());
    })
    .catch((e) => {
      console.log(e)
    });
}

downloadFile = () => {
  try {
      const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        this.actualDownload();
      } else {
        Alert.alert('Permission Denied!', 'You need to give storage permission to download the file');
      }
    } catch (err) {
      console.warn(err);
    } 
}

render(){
  <TouchableOpacity onPress={this.downloadFile}>
    <Text>Download!!!</Text>
  </TouchableOpacity>
}

注意:对于android 6或更高版本,您需要在运行时请求存储权限


11
投票

ios/android 最新工作解决方案

按照 mosabbir tuhin 的答案,然后使用我的函数 actualDownload() 和 PermissionFunc() 使 pdf 也可以在 ios 上工作。

const permissionFunc = async () => {
    if (Platform.OS == 'ios') {
        actualDownload();
    } else {
        if (downloaded) {
            try {
                const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);
                if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                    actualDownload();
                } else {
                    showSnackbar('You need to give storage permission to download the file');
                }
            } catch (err) {
                console.warn(err);
            }
        }
        else {
            showSnackbar('File is already downloaded.');
        }
    }
}

const actualDownload = () => {
    const { dirs } = RNFetchBlob.fs;
    const dirToSave = Platform.OS == 'ios' ? dirs.DocumentDir : dirs.DownloadDir
    const configfb = {
        useDownloadManager: true,
        notification: true,
        mediaScannable: true,
        title: pdfInfo.pdf,
        path: `${dirToSave}/${pdfInfo.pdf}`,
    }
    const configOptions = Platform.select({
        ios: {
            title: configfb.title,
            path: configfb.path,
            appendExt: 'pdf',
        },
        android: configfb,
    });

    console.log('The file saved to 23233', configfb, dirs);

    RNFetchBlob.config(configOptions)
        .fetch('GET', `https://aquatherm.s3.ap-south-1.amazonaws.com/pdfs/${pdfInfo.pdf}`, {})
        .then((res) => {
            if (Platform.OS === "ios") {
                RNFetchBlob.ios.previewDocument(configfb.path);
            }
            setisdownloaded(false)
            if (Platform.OS == 'android') {
                showSnackbar('File downloaded');
            }
            console.log('The file saved to ', res);
        })
        .catch((e) => {
            setisdownloaded(true)
            showSnackbar(e.message);
            console.log('The file saved to ERROR', e.message)
        });
}

0
投票

这是一个完全有效的下载处理程序,灵感来自 Ajmal 的答案,还解决了我使用他的代码在 Android 上下载时遇到的问题:

export const handleDownload = async ({url, fileName}) => {
  try {
    const isGranted = await requestStoragePermission();
    if (!isGranted) {
      showToast({
        type: 'error',
        title: 'error',
        subTitle:
          'required permissions not granted. please enable the recording permission from settings',
      });
      return;
    }

    const {config, fs} = RNFetchBlob;

    const dirToSave = isIos ? fs.dirs.DocumentDir : fs.dirs.DownloadDir;
    const configfb = {
      addAndroidDownloads: {
        useDownloadManager: true,
        notification: true,
        mediaScannable: true,
        title: fileName,
        path: `${dirToSave}/${fileName}`,
      },
    };

    const configOptions = Platform.select({
      ios: {
        title: fileName,
        path: `${dirToSave}/${fileName}`,
      },
      android: configfb,
    });
    config(configOptions)
      .fetch('GET', url)
      .then(res => {
        if (isIos) {
          RNFetchBlob.ios.previewDocument(res?.path());
        } else {
          showToast({
            type: 'success',
            title: 'success',
            subTitle: 'file downloaded successfully',
          });
        }
      })
      .catch(error => {
        showToast({
          type: 'error',
          title: 'error',
          subTitle: 'failed to download file',
        });
      });
  } catch (error) {
    showToast({
      type: 'error',
      title: 'error',
      subTitle: 'failed to download file',
    });
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.