一些配置介绍
import DocumentPicker from 'react-native-document-picker';
const FileTypes = {
All: DocumentPicker.types.allFiles,// All document types, on Android this is */*, on iOS is public.content (note that some binary and archive types do not inherit from public.content)
Image: DocumentPicker.types.images, // All image types (image/* or public.image)
Text: DocumentPicker.types.plainText, // Plain text files ie: .txt (text/plain or public.plain-text)
Audio: DocumentPicker.types.audio, // All audio types (audio/* or public.audio)
PDF: DocumentPicker.types.pdf, // PDF documents (application/pdf or com.adobe.pdf)
Zip: DocumentPicker.types.zip, // Zip files (application/zip or public.zip-archive)
Csv: DocumentPicker.types.csv, //Csv files (text/csv or public.comma-separated-values-text)
};
let Manager = {
// Pick a single file
pickerSingleFile: (fileType, callback, errorCallback) => {
try {
DocumentPicker.pick({
type: [FileTypes[fileType]],
}).then(res => {
console.log(
res.uri,
res.type, // mime type
res.name,
res.size
);
if (callback) {
callback(res);
}
}).catch(error => {
console.log(error);
if (errorCallback) {
errorCallback(error);
}
});
} catch (err) {
if (errorCallback) {
errorCallback(err);
}
if (DocumentPicker.isCancel(err)) {
// User cancelled the picker, exit any dialogs or menus and move on
} else {
throw err;
}
}
},
PickMultipleFiles: (fileType, callback, errorCallback) => {
// Pick multiple files
try {
DocumentPicker.pickMultiple({
type: [FileTypes[fileType]],
}).then(results => {
for (const res of results) {
console.log(
res.uri,
res.type, // mime type
res.name,
res.size
);
}
if (callback) {
callback(results);
}
});
} catch (err) {
if (errorCallback) {
errorCallback(err);
}
if (DocumentPicker.isCancel(err)) {
// User cancelled the picker, exit any dialogs or menus and move on
} else {
throw err;
}
}
},
};
module.exports = Manager;
实际使用,代码如下图所示
还需要借助另外一个组件:react-native-fetch-blob
pickFile = async () => {
try {
const res = await DocumentPicker.pick({
type: [DocumentPicker.types.allFiles],
});
console.log(res.uri);
//output: content://com.android.providers.media.documents/document/image%3A4055
RNFetchBlob.fs
.stat(res.uri)
.then((stats) => {
console.log(stats.path);
//output: /storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20200831-WA0019.jpg
})
.catch((err) => {
console.log(err);
});
} catch (err) {
if (DocumentPicker.isCancel(err)) {
} else {
throw err;
}
}};
代码二:直接用react-native-fetch-blob
引入
import RNFileSelector from "react-native-file-selector";
const RNFS = require('react-native-fs');
函数
// 上传附件
onSwitchToFile = () => {
RNFileSelector.Show(
{
title: '请选择文件',
onDone: (path) => {
RNFS.read('file://' + path , 20971520 , 0 , 'base64')
.then(res => {
const size = res.length - (res.length / 8) * 2
console.log('文件大小为: ' + (size / 1024 / 1024).toFixed(2) + 'M' )
if (size > 10485760) {
toast("文件大小不能超过10M!")
return false
}
let url = global.HOST + "media/upload"
let formData = new FormData()
let file = {
uri: 'file://' + path,
type: 'multipart/form-data',
name: path || 'file',
}
formData.append("file", file)
Net.upload(url, formData, res => {
if (res.result === 0) {
let fileName = path.substr(path.lastIndexOf("/") + 1)
this.setState({
fileName,
fileUrl: res.ret
})
}
})
})
.catch(error => {
toast('文件上传失败!请重试!')
console.log(error)
})
},
onCancel: () => {
console.log('cancelled')
}
}
)
}
页面中:
<SafeAreaView style={{ backgroundColor: '#F2F2F2' }}>
<ScrollView contentContainerStyle={{ padding: 10, backgroundColor: '#FFF', marginTop: 10 }}>
<View style={[Styles.itemTitleContainer, { borderBottomWidth: 0 }]}>
<View style={Styles.item_title}>
<Text style={Styles.itemText}>上传附件</Text>
</View>
<View>
<TouchableOpacity
style={{
borderColor: '#DDD',
borderWidth: .5,
paddingLeft: 15,
paddingRight: 15,
paddingTop: 8,
paddingBottom: 8,
flexDirection:"row",
alignItems: 'center',
justifyContent: 'center'
}}
onPress={() => this.onSwitchToFile()}
>
<Text>
{
this.state.fileName
? this.state.fileName
: <Ionicons style={{ color: "#DDD" }} name="md-add" size={25} />
}
</Text>
</TouchableOpacity>
{
this.state.fileName &&
<View
style={{
position: 'absolute',
top: -5,
right: -5
}}
>
<Text
onPress={() => {
this.setState({
fileName: null,
fileUrl: null
})
}}
style={{
width: 12,
height: 12,
borderRadius: 6,
backgroundColor: '#ddd',
fontSize: 10,
textAlign: 'center',
lineHeight: 12,
color: '#fff'
}}
>
x
</Text>
</View>
}
</View>
</View>
</ScrollView>