1:通过函数回调,传递一个string或者一个object 不能传递json如果想传递json格式 可以将json转成string 到react端再解析会json
2:通过promise 使用async,await 传递一个map
3:通过事件native端可以发送参数到js 传递一个map
1:代码:
/**
* index.android.js
*/
'use strict';
import React, {
AppRegistry,
Component,
StyleSheet,
Text,
Image,
TouchableHighlight,
View,
NativeModules
} from 'react-native';
var path = require('./Lighthouse.jpg');
var QRFromAlbum = require('./mymodule/QRFromAlbum');
class TestQRAndroidExample extends React.Component{
constructor(props) {
super(props);
this.state = {
torchMode: 'off',
cameraType: 'back',
flag:false,
Imagepath:null,
};
}
onClick(){
<strong><span style="font-size:18px;"> QRFromAlbum.chooseImage((res)=>{
var json = JSON.parse(res);
var path = json.imagepath;//得到图片的路径
this.setState({
flag:true,
Imagepath:path,
});</span></strong>
});
}
render() {
if(this.state.flag){
console.log("path:"+this.state.Imagepath);
return (<View style={styles.main}>
<Image style={styles.containerImageView}
source={{uri:this.state.Imagepath}}>
</Image>
</View>
);
}else{
return (<View style={styles.main}>
<TouchableHighlight style={styles.button} underlayColor='#99d9fe' onPress={()=>{this.onClick();}}>
<Text style={styles.buttontext}>打开相册 </Text>
</TouchableHighlight>
</View>
);
}
}
};
var styles = StyleSheet.create({
containerTextView: {
flex: 1,
},
containerImageView:{
flex: 1,
position:'relative',
width:300,
height:300,
flexDirection:'row',
justifyContent:'center',
},
text:{
position:'relative',
color:'white',
flex:1,
bottom:160,
left:90,
height:60,
fontSize: 15,
fontWeight: 'bold',
flexDirection:'row',
justifyContent:'center',
},
button:{
position:'relative',
flex:1,
backgroundColor:'#48BBEC',
bottom:170,
left:100,
height:35,
flexDirection:'row',
justifyContent:'center',
borderRadius:10,
},
buttontext:{
flex:1,
fontSize:15,
color:'white',
alignSelf:'center',
},
main:{
flex:1,
position:'absolute',
},
});
AppRegistry.registerComponent('TestUI', () => TestQRAndroidExample);
Java代码:
module部分
package com.nativemodule;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.testui.BuildConfig;
import java.util.HashMap;
import java.util.Map;
/**
* Created by wyq on 2016/1/21.
*/
public class QRFromAlbum extends ReactContextBaseJavaModule {
private static final String TAG = "QRFromAlbum";
private ReactContext reactContext;
public QRFromAlbum(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "QRFromAlbum";
}
@ReactMethod
public void chooseImage(final Callback callback) {
Log.i(TAG, "chooseImage");
QRCodeHelper.chooseImage(callback);
}
@Override
public Map<String, Object> getConstants() {
Map<String, Object> Constants = new HashMap<>();
return Constants;
}
}
QRCodeHelper代码:
package com.nativemodule;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Vibrator;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import com.facebook.react.ReactActivity;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.util.FileUtils;
import com.util.ImageUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import cn.bingoogolapple.qrcode.core.QRCodeView;
import cn.bingoogolapple.qrcode.zxing.ZXingUtils;
import cn.bingoogolapple.qrcode.zxing.ZXingView;
/**
* Created by wyq on 2015/12/22.
*/
public class QRCodeHelper{
private static final String TAG = "QRFromAlbum";
public static final int REQ = 10086;
private static final int CODE_SUCCESS = 0;
private static final int CODE_CAMERA_ERROR = -1;
private static final int CODE_IMAGE_ERROR = -2;
public static final String TYPE_IMAGE = "IMAGE";
public static final String TYPE_CAMERA = "CAMERA";
private static Activity activity;
private ScanImageTask mScanImageTask;
private static Callback callback;
public QRCodeHelper(Activity activity) {
QRCodeHelper.activity = activity;
}
public static void chooseImage(final Callback callback){
QRCodeHelper.callback = callback;
Intent intent = new Intent();
if(Build.VERSION.SDK_INT<19){
intent.setAction(Intent.ACTION_GET_CONTENT);
}else{
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
}
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
QRCodeHelper.activity.startActivityForResult(intent, REQ, null);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "onActivityResult ");
if (REQ != requestCode) {
return;
}
if(Activity.RESULT_OK == resultCode) {
File imageFile = FileUtils.getUriFile(QRCodeHelper.activity, data.getData());
if (imageFile != null) {
mScanImageTask = new ScanImageTask(imageFile);
mScanImageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
sendResult(CODE_IMAGE_ERROR, "图片不存在", null, null, null);
}
} else {
}
}
/**
* 振动
*/
private void vibrate() {
Vibrator vibrator = (Vibrator) QRCodeHelper.activity.getSystemService(((Context)QRCodeHelper.activity).VIBRATOR_SERVICE);
vibrator.vibrate(200);
}
<strong><span style="font-size:18px;"> private void sendResult(int code, String msg, String result, String type,String imagepath) {
Log.i(TAG, "imagepath:"+imagepath);
JSONObject json = new JSONObject();
try {
json.put("code", code);
json.put("msg", msg);
JSONObject data = new JSONObject();
data.put("result", result);
data.put("type", type);
json.put("data", data);
json.put("imagepath",imagepath);
json.put("length",4);
} catch (JSONException e) {
e.printStackTrace();
}
if(QRCodeHelper.callback==null){
Log.i(TAG, "sendResult QRCodeHelper callback");
}
QRCodeHelper.callback.invoke(json.toString());
}</span></strong>
private class ScanImageTask extends AsyncTask<Void, Void, String> {
private File file;
private Bitmap bitmap;
private MultiFormatReader imageScanReader = ZXingUtils.newDefaultReader();
private String ImagePath = null;
public ScanImageTask(File file) {
this.file = file;
}
@Override
public String doInBackground(Void... params) {
ImagePath = "file://"+file.getAbsolutePath();
bitmap = ImageUtils.getSmallBitmap(file.getAbsolutePath(), 1000, 1000);
Result result = ZXingUtils.decode(bitmap, imageScanReader);
if(result != null) {
return result.getText();
}
return null;
}
@Override
public void onPostExecute(String result) {
if(mScanImageTask == this) {
mScanImageTask = null;
}
if (result != null) {
Log.i(TAG, "result:" + result);
vibrate();
sendResult(CODE_SUCCESS, "success", result, TYPE_IMAGE,ImagePath);
} else {
Log.i(TAG, "result=null");
sendResult(CODE_IMAGE_ERROR, "解析二维码失败", null, null, ImagePath);
}
}
@Override
protected void onCancelled() {
if(mScanImageTask == this) {
mScanImageTask = null;
}
}
}
}
2 代码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
import React, {
AppRegistry,
NativeModules,
Component,
StyleSheet,
Text,
View,
TouchableHighlight
} from 'react-native';
var ImageChooser = NativeModules.ImageChooserModule;
class lightappbuilder extends Component {
<strong><span style="font-size:18px;"> async onClick(){
var data = await ImageChooser.chooseImage().catch((err)=>{console.log(err);});
console.log(data);
}</span></strong>
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.android.js
</Text>
<TouchableHighlight style={styles.container} onPress={()=>{this.onClick();}}>
<Text style={styles.instructions}>
Shake or press menu button for dev menu
</Text>
</TouchableHighlight>
</View>
);
}
}
const 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,
},
});
AppRegistry.registerComponent('lightappbuilder', () => lightappbuilder);
Java代码:
/**
* Created by wyq on 2016/3/8.
*/
public class ImageChooser extends ReactContextBaseJavaModule implements ActivityEventListener {
private Promise cur_promise;
private static int Request = 10086;
public ImageChooser(ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addActivityEventListener(this);
}
@Override
public String getName() {
return "ImageChooserModule";
}
@ReactMethod
public void chooseImage(final Promise promise){
Activity cur_activity = getCurrentActivity();
if (cur_activity!=null) {
cur_promise = promise;
}else {
promise.resolve("Activity doesn't exist");
return ;
}
startActivity(cur_activity);
}
private void startActivity(Activity activity){
Intent intent = new Intent();
if (Build.VERSION.SDK_INT<19){
intent.setAction(Intent.ACTION_GET_CONTENT);
} else {
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
}
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
activity.startActivityForResult(intent,ImageChooser.Request);
}
private void resolvePromise(WritableMap map) {
if (cur_promise != null) {
cur_promise.resolve(map);
cur_promise = null;
}
}
private void rejectPromise(String reason) {
if (cur_promise != null) {
cur_promise.resolve(reason);
cur_promise = null;
}
}
private String getNameFromUri(Uri contentUri) {
if (contentUri.getScheme().equals("file")) {
return contentUri.getLastPathSegment();
}
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
return null;
}
String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME};
Cursor metaCursor = currentActivity.getContentResolver().query(contentUri, projection, null, null, null);
if (metaCursor != null) {
try {
if (metaCursor.moveToFirst()) {
return metaCursor.getString(0);
}
} finally {
metaCursor.close();
}
}
return contentUri.getLastPathSegment();
}
private long getSizeFromUri(Uri contentUri) {
if (contentUri.getScheme().equals("file")) {
return new File(contentUri.getPath()).length();
}
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
return 0;
}
Cursor cursor = currentActivity.getContentResolver().query(contentUri, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
long size = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE));
cursor.close();
return size;
}
return 0;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (ImageChooser.Request != requestCode) {
return;
}
if(Activity.RESULT_OK == resultCode) {
try {
Uri uri = data.getData();
if (uri != null) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
String path = FileUtils.getUriPath(getCurrentActivity(),uri);
if (path != null) {
BitmapFactory.decodeFile(path, options);
WritableMap map = Arguments.createMap();
map.putInt("height", options.outHeight);
map.putInt("width", options.outWidth);
String size = Formatter.formatFileSize(getCurrentActivity(), getSizeFromUri(uri));
map.putString("size", size);
map.putString("name",getNameFromUri(uri));
map.putString("uri", uri.toString());
map.putString("path","fill://"+path);
resolvePromise(map);
} else {
rejectPromise("Failed resolve image path");
}
} else {
rejectPromise("Failed to pick image");
}
} catch (Exception e) {
rejectPromise(e.getMessage());
}
} else if(Activity.RESULT_CANCELED==resultCode){
rejectPromise("Image picker was cancelled");
}
}
}
3: 参考
点击打开链接