xwp 21 react native Android 上传图片 - nuanxin1111/react GitHub Wiki

选择图片

使用 https://github.com/marcshilling/react-native-image-picker

上传图片

使用 https://github.com/PhilippKrone/react-native-fileupload

参照上述地址做配置,在修改 项目根目录/android/app/src/main/java/com/项目根目录/MainActivity.java 时原文档版本太低,参照以下配置

package com.camerarolldemo;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;

import java.util.Arrays;
import java.util.List;

import android.content.Intent; // import
import com.imagepicker.ImagePickerPackage; // import

import com.yoloci.fileupload.FileUploadPackage;  // import

public class MainActivity extends ReactActivity {

    private ImagePickerPackage mImagePicker; // <--- ADD THIS

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "CameraRollDemo";
    }

    /**
     * Returns whether dev mode should be enabled.
     * This enables e.g. the dev menu.
     */
    @Override
    protected boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
    }

   /**
   * A list of packages used by the app. If the app uses additional views
   * or modules besides the default ones, add more packages here.
   */
    @Override
    protected List<ReactPackage> getPackages() {

      mImagePicker = new ImagePickerPackage(this); // <--- AND THIS

      return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        mImagePicker, // <--- AND THIS
        new FileUploadPackage()  // <--- AND THIS
      );
    }

// AND ADD THIS WHOLE METHOD
    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        mImagePicker.handleActivityResult(requestCode, resultCode, data);

    }
}

使用时

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */
'use strict';

var React = require('react-native');
var ImagePickerManager = require('NativeModules').ImagePickerManager;
var FileUpload = require('NativeModules').FileUpload;

var {
  AppRegistry,
  StyleSheet,
  Text,
  Image,
  View,
  TouchableOpacity, 
} = React;

var CameraRollDemo = React.createClass({

  uploadfile: function () {

    console.log('in uploadfile');
    console.log(this.state.filepath);
    console.log('in uploadfile');

    var obj = {
        uploadUrl: 'http://123.57.211.212:33333/itcastcpp/wxbase/uploadfile/',
        method: 'POST', // default 'POST',support 'POST' and 'PUT'
        headers: {
          'Accept': 'application/json',
        },
        fields: {
            'hello': 'world',
        },
        files: [
          {
            name: 'one', // optional, if none then `filename` is used instead
            filename: 'one.w4a', // require, file name
            filepath: this.state.filepath, // require, file absoluete path
            filetype: null, // options, if none, will get mimetype from `filepath` extension
          },
        ]
    };
    FileUpload.upload(obj, function(err, result) {
      console.log('upload:', err, result);
    })
  },



  // Set the initial state
  getInitialState: function() {
    return {
      avatarSource: null,
      filepath: null,
    };
  },

  launchPicker: function(){
    var options = {
      title: 'Select Avatar', // specify null or empty string to remove the title
      cancelButtonTitle: 'Cancel',
      takePhotoButtonTitle: 'Take Photo...', // specify null or empty string to remove this button
      chooseFromLibraryButtonTitle: 'Choose from Library...', // specify null or empty string to remove this button
      customButtons: {
        'Choose Photo from Facebook': 'fb', // [Button Text] : [String returned upon selection]
      },
      cameraType: 'back', // 'front' or 'back'
      mediaType: 'photo', // 'photo' or 'video'
      videoQuality: 'high', // 'low', 'medium', or 'high'
      maxWidth: 0, // photos only
      maxHeight: 0, // photos only
      aspectX: 2, // aspectX:aspectY, the cropping image's ratio of width to height
      aspectY: 1, // aspectX:aspectY, the cropping image's ratio of width to height
      quality: 1, // photos only
      angle: 0, // photos only
      allowsEditing: false, // Built in functionality to resize/reposition the image
      noData: false, // photos only - disables the base64 `data` field from being generated (greatly improves performance on large photos)
      storageOptions: { // if this key is provided, the image will get saved in the documents/pictures directory (rather than a temporary directory)
        skipBackup: true, // image will NOT be backed up to icloud
        path: 'images' // will save image at /Documents/images rather than the root
      }
    };


    ImagePickerManager.showImagePicker(options, (response) => {
      console.log('Response = ', response);

      if (response.didCancel) {
        console.log('User cancelled image picker');
      }
      else if (response.error) {
        console.log('ImagePickerManager Error: ', response.error);
      }
      else if (response.customButton) {
        console.log('User tapped custom button: ', response.customButton);
      }
      else {
        // You can display the image using either data:
     //   const mysource = {uri: 'data:image/jpeg;base64,' + response.data, isStatic: true};

        // uri (on iOS)
    //    const mysource = {uri: response.uri.replace('file://', ''), isStatic: true};
        // uri (on android)
        const mysource = {uri: response.uri, isStatic: true};

        this.setState({
          avatarSource: mysource,
          filepath: response.path
        });


        this.uploadfile();

      }
    });
  },


  render: function() {
    return (
      <View style={styles.container}>
        <Image style={styles.image} source={this.state.avatarSource} />
        <TouchableOpacity onPress={this.launchPicker}>
          <Text>Select an image...</Text>
        </TouchableOpacity>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },

  image: {
    height: 100,
    width: 100
  },

  resizeMode: {
    width: 90,
    height: 60,
    borderWidth: 0.5,
    borderColor: 'black'
  },

});

AppRegistry.registerComponent('CameraRollDemo', () => CameraRollDemo);

注意事项

django里面接收时对提交上来的数据要进行csrf验证,可在视图函数前加’@csrf_exempt‘

from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def uploadfile(request):
    print '*'*30
    print request.FILES['image']
    aa=request.FILES['image']
    print type(aa)
    data = request.FILES['image'] 
    path = default_storage.save('dd.jpg', ContentFile(data.read()))
    print '*'*30
    return HttpResponse("ok")
-- INSERT --                      
⚠️ **GitHub.com Fallback** ⚠️