Reputation: 1236
I'm using react-native-fs to download a file(pdf, word, excel, png etc.) and I need to open it in other application. Is it possible to open downloaded file with Linking or better open a dialog with possible apps like when using Sharing? Linking
in the code below tries to open the file but it closes immediately without any notification, but my app is still working fine. Is there some special way to build URLs for deep linking for a specific file type? Any ideas for the best solution?
I see that there is old package react-native-file-opener but it's no longer maintained. This solution would be great.
Simplified code for download component:
import React, { Component } from 'react';
import { Text, View, Linking, TouchableOpacity } from 'react-native';
import { Icon } from 'react-native-elements';
import RNFS from 'react-native-fs';
import { showToast } from '../../services/toasts';
class DownloadFile extends Component {
state = {
isDone: false,
};
handleDeepLinkPress = (url) => {
Linking.openURL(url).catch(() => {
showToast('defaultError');
});
};
handleDownloadFile = () => {
RNFS.downloadFile({
fromUrl: 'https://www.toyota.com/content/ebrochure/2018/avalon_ebrochure.pdf',
toFile: `${RNFS.DocumentDirectoryPath}/car.pdf`,
}).promise.then(() => {
this.setState({ isDone: true });
});
};
render() {
const preview = this.state.isDone
? (<View>
<Icon
raised
name="file-image-o"
type="font-awesome"
color="#f50"
onPress={() => this.handleDeepLinkPress(`file://${RNFS.DocumentDirectoryPath}/car.pdf`)}
/>
<Text>{`file://${RNFS.DocumentDirectoryPath}/car.pdf`}</Text>
</View>)
: null;
return (
<View>
<TouchableOpacity onPress={this.handleDownloadFile}>
<Text>Download File</Text>
</TouchableOpacity>
{preview}
</View>
);
}
}
export default DownloadFile;
Upvotes: 15
Views: 27719
Reputation: 87
Opening Files from url with Default Applications in React Native
To open various types of files like PDF, Word document, Excel sheet, image, and more on a device with their default applications in React Native, you can follow these steps:
Install Dependencies
I'm using react-native-fs
package alternate to RN fetch blob
, which provides file system functionality.
You also need react-native-file-viewer
to open file with it's default application.
npm install react-native-fs
npm install react-native-file-viewer
Here's a function that allows you to open the document. You need to pass the URL of the file you want to open and the desired file name with extension (.pdf, .png, .csv, .xls, etc).
import FileViewer from "react-native-file-viewer";
export async function openDocument(url: string, fileName: string /* e.g., file.pdf; image.png, document.csv*/) {
let RNFS = require('react-native-fs');
return new Promise((resolve, reject) => {
try {
let originalName = fileName
const localFile = `${RNFS.DocumentDirectoryPath}/${originalName}`;
console.log("localFile ===>", localFile);
const options = {
fromUrl: url,
toFile: localFile,
};
RNFS.downloadFile(options)
.promise.then(() => FileViewer.open(localFile))
.then((res) => {
// Success
console.log('res', res);
resolve(res)
})
.catch((error) => {
// Error
console.log('error', error);
reject(error)
});
} catch (error) {
console.log(error)
reject(error)
toastAndroid('File Not Available')
}
})
}
.pdf
, .png
, .csv
) when calling this function. The extension is crucial for it to work correctly.Upvotes: 0
Reputation: 51
Use react-native-file-viewer to preview file and react-native-f to get the path to file. Like this:
import RNFS from 'react-native-fs';
import FileViewer from 'react-native-file-viewer';
const returnFilePath = fileName => {
const dirPath =
Platform.OS === 'ios'
? `${RNFS.DocumentDirectoryPath}`
: `${RNFS.DownloadDirectoryPath}`;
const filePath = dirPath + `/${fileName}`;
return filePath;
};
export function previewFile(filePath) {
FileViewer.open(filePath)
.then(() => {
console.log('Success');
})
.catch(_err => {
console.log(_err);
});
}
Upvotes: 1
Reputation: 1236
After some research, I decided to use react-native-fetch-blob. From version 0.9.0
it's possible to open downloaded file with Intent and use Download Manager
. It also has API for iOS for opening documents.
Code now:
...
const dirs = RNFetchBlob.fs.dirs;
const android = RNFetchBlob.android;
...
handleDownload = () => {
RNFetchBlob.config({
addAndroidDownloads: {
title: 'CatHat1.jpg',
useDownloadManager: true,
mediaScannable: true,
notification: true,
description: 'File downloaded by download manager.',
path: `${dirs.DownloadDir}/CatHat1.jpg`,
},
})
.fetch('GET', 'http://www.swapmeetdave.com/Humor/Cats/CatHat1.jpg')
.then((res) => {
this.setState({ path: res.path() });
})
.catch((err) => console.log(err));
};
...
render() {
...
<Icon
raised
name="file-pdf-o"
type="font-awesome"
color="#f50"
onPress={() => android.actionViewIntent(this.state.path, 'image/jpg')}
...
}
Upvotes: 11