目录:
- 思路
- 安装中间件
- 获取用户相册/相机权限,以及主要步骤
- 调用接口,实现上传图片文件
思路
- 获取用户相册/相机权限;
- 实现本地相册选择/相机拍摄;
- 封装上传接口,将照片上传到服务器;
- 将选择的照片,展示出来(注意点:展示时,需要使用本地路径,而不是服务器地址);
具体步骤
1. 安装中间件 react-native-image-picker
版本:
"react": "16.8.3",
"react-native": "0.59.9",
"react-native-image-picker": "0.27.0"
2. 获取用户相册/相机权限,以及主要步骤
- 设置选择照片的弹窗样式
- 调用
ImagePicker.showImagePicker
函数选择本地相册/拍照
- 设置获取相机权限提示
- 区分
IOS
/ Android
上传的文件是否加前缀 file//
- 调用上传接口
uploadEquipImg
【主要代码如下】
...
import ImagePicker from 'react-native-image-picker';
import {
uploadEquipImg
} from '../../action/TestAction'; // 上传图片接口文件,此函数在下一步详细描述
...
class Test extends Component {
constructor(props) {
super(props);
this.state = {
...
localPhoOption: [] // 存储本地文件路径,用户本地展示图片
...
}
}
// 添加图片 点击
handleAddPicCheck() {
// console.warn('添加图片------check')
let { localPhoOption } = this.state
let { props } = this
let that = this
const options = {
title: '选择图片',
cancelButtonTitle: '取消',
takePhotoButtonTitle: '拍照',
chooseFromLibraryButtonTitle: '相册',
cameraType: 'back',
mediaType: 'photo',
videoQuality: 'high',
durationLimit: 10,
maxWidth: 720,
maxHeight: 1280,
aspectX: 2,
aspectY: 1,
quality: 1,
angle: 0,
allowsEditing: false,
noData: false,
storageOptions: {
skipBackup: true,
path: 'PickLocalImg' // 存储本地地址
}
};
ImagePicker.showImagePicker(options, async (res) => {
if (res.didCancel) {
console.log('User cancelled photo picker');
}
else if (res.error) {
// 用户选择不授权时,提醒以下信息
console.log('ImagePicker Error: ', res.error);
if(res.error.indexOf('Camera permissions not granted') > -1){
Alert.alert(('提示信息', 'APP需要使用相机,请打开相机权限允许APP使用'), [{
text: '设置',
onPress: () => {
Linking.openURL('app-settings:')
.catch(err => console.log('error', err))
}
},{
text: '取消'
}])
}
if(res.error.indexOf('Photo library permissions not granted') > -1){
Alert.alert('提示信息', 'APP需要使用相册,请打开相册权限允许APP使用', [{
text: '设置',
onPress: () => {
Linking.openURL('app-settings:')
.catch(err => console.log('error', err))
}
},{
text: '取消'
}]);
}
}
else if (res.customButton) {
console.log('User tapped custom button: ', res.customButton);
} else {
// 用户授权并选择照片/拍照后,调用接口
let source; //保存选中的图片
if (Platform.OS === 'android') {
source = res.uri;
} else {
source = res.uri.replace('file://','');
}
const formData = new FormData();
// 文件类型根据对应的后端接口改变!!!
let file = { uri: source, type: 'multipart/form-data', name: res.fileName };
formData.append('file',file);
let params = {
formData
}
//上传图片接口
let imgResult = await uploadEquipImg(params);
if(imgResult.error_code == 0) {
// 提交订单
show('上传成功');
let {url} = imgResult.data
localPhoOption.push(source); // 存储本地图片地址,方便在APP中本地查看展示,注意⚠️不是后端返回的图片地址
that.setState({
localPhoOption
});
} else {
let error_msg = imgResult.error_msg || imgResult.message
show(error_msg);
}
}
})
}
...
render() {
let { state } = this
return (
添加图片
{/* 显示上传后的照片 */}
{
state.localPhoOption.length
? state.localPhoOption.map((item, index) => this.renderPicItem(item, index) )
: null
}
this.handleAddPicCheck()}
>
{/* 点击此图,调用上传图片,一般此图是个➕号 的样子*/}
)
}
// 返回增加的图片
renderPicItem(item, index) {
return (
)
}
...
}
3. 封装的图片上传,请求后端接口的函数 uploadEquipImg
,需要 formData
对象的格式,即【调用上传接口】,实现图片上传;
【文件 `TestAction` 内容如下:】
import {UploadRequest} from './util'; // 该函数内容在下面哈
...
// 图片上传
export const uploadEquipImg = async (params) => {
let { formData } = params
return await UploadRequest('自己的接口地址', formData)
}
...
4. 【fetch
上传】文件的封装;
【文件 `util` 内容如下:】
...
// 上传
export const UploadRequest(url, datas) {
let BaseUrl = 'http://www.baidu.com' // 域名地址,根据自己的修改
const params = {
method: 'POST',
body: datas,
headers: {
'Content-Type': 'multipart/form-data'
},
timeout: 5000 // 5s超时
};
return fetch(`${BaseUrl}${url}`, params)
.then(response => response.json())
.then(data => data)
.catch(error => {
return {error_code: -3, error_msg:'请求异常,请重试'}
})
}
...
写给自己的随笔,有问题欢迎指出