React Native 使用react-native-image-picker库实现图片上传功能

react

react-native-image-picker使用

1, 首先,安装下该插件。

npm install react-native-image-picker@latest --save

  • 1

2, 针对Android和iOS平台分别进行配置

## android 平台配置

1,在android/settings.gradle文件中添加如下代码:

include ':react-native-image-picker'

project(':react-native-image-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-picker/android')

  • 1
  • 2

2,在android/app/build.gradle文件的dependencies中添加如下代码:

compile project(':react-native-image-picker')

  • 1

3,在AndroidManifest.xml文件中添加权限:

<uses-permission android:name="android.permission.CAMERA" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  • 1
  • 2

4,最后在MainApplication.Java文件中添加如下代码:

import com.imagepicker.ImagePickerPackage;

new ImagePickerPackage()

  • 1
  • 2

这样Android环境就配置好了。

iOS平台配置

1,打开Xcode打开项目,点击根目录,右键选择 Add Files to ‘XXX’,选中项目中的该路径下的文件即可:node_modules -> react-native-image-picker -> ios -> select RNImagePicker.xcodeproj

2,添加成功后使用link命令:react-native link react-native-image-picker 。

3,打开项目依次使用Build Phases -> Link Binary With Libraries将RNImagePicker.a添加到项目依赖。

4,对于iOS 10+设备,需要在info.plist中配置NSPhotoLibraryUsageDescription和NSCameraUsageDescription。

react-native-image-picker示例

为了项目使用的方便,我们将其封装为一个组件CameraButton.js。代码如下:

import React from 'react'

import {

TouchableOpacity,

StyleSheet,

Platform,

ActivityIndicator,

View,

Text,

ToastAndroid

} from 'react-native'

var ImagePicker = require('react-native-image-picker');

import Icon from 'react-native-vector-icons/Ionicons';

const options = {

title: '选择图片',

cancelButtonTitle: '取消',

takePhotoButtonTitle: '拍照',

chooseFromLibraryButtonTitle: '图片库',

cameraType: 'back',

mediaType: 'photo',

videoQuality: 'high',

durationLimit: 10,

maxWidth: 600,

maxHeight: 600,

aspectX: 2,

aspectY: 1,

quality: 0.8,

angle: 0,

allowsEditing: false,

noData: false,

storageOptions: {

skipBackup: true,

path: 'images'

}

};

class CameraButton extends React.Component {

constructor(props){

super(props);

this.state = {

loading:false

}

}

render() {

const {photos,type} = this.props;

let conText;

if(photos.length > 0){

conText = (<View style={styles.countBox}>

<Text style={styles.count}>{photos.length}</Text>

</View>);

}

return (

<TouchableOpacity

onPress={this.showImagePicker.bind(this)}

style={[this.props.style,styles.cameraBtn]}>

<View>

<Icon name="md-camera" color="#aaa" size={34}/>

{conText}

</View>

</TouchableOpacity>

)

}

showImagePicker() {

ImagePicker.showImagePicker(options, (response) => {

if (response.didCancel) {

console.log('User cancelled image picker');

}

else if (response.error) {

console.log('ImagePicker Error: ', response.error);

}

else {

let source;

if (Platform.OS === 'android') {

source = {uri: response.uri, isStatic: true}

} else {

source = {uri: response.uri.replace('file://', ''), isStatic: true}

}

let file;

if(Platform.OS === 'android'){

file = response.uri

}else {

file = response.uri.replace('file://', '')

}

this.setState({

loading:true

});

this.props.onFileUpload(file,response.fileName||'未命名文件.jpg')

.then(result=>{

this.setState({

loading:false

})

})

}

});

}

}

const styles = StyleSheet.create({

cameraBtn: {

padding:5

},

count:{

color:'#fff',

fontSize:12

},

fullBtn:{

justifyContent:'center',

alignItems:'center',

backgroundColor:'#fff'

},

countBox:{

position:'absolute',

right:-5,

top:-5,

alignItems:'center',

backgroundColor:'#34A853',

width:16,

height:16,

borderRadius:8,

justifyContent:'center'

}

});

export default CameraButton;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134

然后在需要使用的地方引入。

import CameraButton from '../../component/huar/cameraButton'

<CameraButton style={styles.cameraBtn}

photos={[]}

onFileUpload={this.onFileUpload} />

点击上传事件:

onFileUpload(file, fileName){

return this.props.uploadAvatar({

id: this.props.user.ID,

type:'logo',

obj:'user',

corpId: this.props.cropId

}, file, fileName)}

Action请求代码:

function actions(dispatch) {

return {

fileUrl,fileName)=>dispatch(Actions.uploadAvatar(params, fileUrl,fileName))

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

actions中的uploadAvatar函数如下。

function uploadAvatar(params, fileUrl, fileName) {

return dispatch=> {

return UserService.uploadImage(params, fileUrl, fileName)

.then(result=> {

dispatch({

type: UPDATE_AVATAR,

path: result.path

})

return result

})

}

}

//UserService.uploadImage代码如下

export function uploadImage(params, fileUrl,fileName) {

return http.uploadFile(`${config.UploadImage}`, params, fileUrl,fileName)

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

UserService函数的http异步上传图片代码如下:

let queryString = require('query-string');

import Storage from './storage'

import {

Platform

} from 'react-native'

const os = Platform.OS;

async function uploadFile(url, params, fileUrl,fileName) {

let Access_Token = await Storage.getItem('Access_Token');

let data = new FormData();

data.append('file', {

uri: fileUrl,

name: fileName,

type: 'image/jpeg'

});

Object.keys(params).forEach((key)=> {

if (params[key] instanceof Date) {

data.append(key, value.toISOString())

} else {

data.append(key, String(params[key]))

}

});

const fetchOptions = {

method: 'POST',

headers: {

'Accept': 'application/json',

'Access_Token': Access_Token ? Access_Token : '',

'UserAgent':os

},

body: data

};

return fetch(url, fetchOptions)

.then(checkStatus)

.then(parseJSON)

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

封装上传

如果上面的实现看的比较复杂,那么我们做如下的封装:

let common_url = 'http://192.168.1.1:8080/';  //服务器地址

let token = ''; //用户登陆后返回的token

function uploadImage(url,params){

return new Promise(function (resolve, reject) {

let formData = new FormData();

for (var key in params){

formData.append(key, params[key]);

}

let file = {uri: params.path, type: 'application/octet-stream', name: 'image.jpg'};

formData.append("file", file);

fetch(common_url + url, {

method: 'POST',

headers: {

'Content-Type': 'multipart/form-data;charset=utf-8',

"x-access-token": token,

},

body: formData,

}).then((response) => response.json())

.then((responseData)=> {

console.log('uploadImage', responseData);

resolve(responseData);

})

.catch((err)=> {

console.log('err', err);

reject(err);

});

});

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

然后在使用的地方:

let params = {

userId:'abc12345', //用户id

path:'file:///storage/emulated/0/Pictures/image.jpg' //本地文件地址

}

uploadImage('app/uploadFile',params )

.then( res=>{

//请求成功

if(res.header.statusCode == 'success'){

//这里设定服务器返回的header中statusCode为success时数据返回成功

upLoadImgUrl = res.body.imgurl; //服务器返回的地址

}else{

//服务器返回异常,设定服务器返回的异常信息保存在 header.msgArray[0].desc

console.log(res.header.msgArray[0].desc);

}

}).catch( err=>{

//请求失败

})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

附:http://lib.csdn.net/article/reactnative/58022?knId=1415
使用fetch+formData实现图片上传

以上是 React Native 使用react-native-image-picker库实现图片上传功能 的全部内容, 来源链接: utcz.com/z/383032.html

回到顶部