目錄:
- 思路
- 安裝中間件
- 獲取用戶相冊/相機權限,以及主要步驟
- 調用接口,實現上傳圖片文件
思路
- 獲取用戶相冊/相機權限;
- 實現本地相冊選擇/相機拍攝;
- 封裝上傳接口,將照片上傳到服務器;
- 將選擇的照片,展示出來(注意點:展示時,需要使用本地路徑,而不是服務器地址);
具體步驟
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 (
<View>
<Text>添加圖片</Text>
<View style={list_common_item.addpic_cont}>
{/* 顯示上傳後的照片 */}
{
state.localPhoOption.length
? state.localPhoOption.map((item, index) => this.renderPicItem(item, index) )
: null
}
<TouchableOpacity
activeOpacity={.8}
onPress={() => this.handleAddPicCheck()}
>
{/* 點擊此圖,調用上傳圖片,一般此圖是個➕號 的樣子*/}
<Image style={icon_style} source={require('../../images/add_icon_large.png')} />
</TouchableOpacity>
</View>
</View>
)
}
// 返回增加的圖片
renderPicItem(item, index) {
return (
<View key={index}>
<TouchableOpacity
activeOpacity={.8}
>
<Image source={{uri: item}} />
</TouchableOpacity>
</View>
)
}
...
}
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:'請求異常,請重試'}
})
}
...
寫給自己的隨筆,有問題歡迎指出