项目中的一个需求:在原生系统中调用第三方SDK识别身份证后将获取的信息和图片返回到React Native JSX页面上展示。
首先React Native与原生通信的方式可以采用CallBack 和Promise,并且通过CallBack的Json和Promise的Map都可以实现多数据的传输;
原生端主要代码实现:
调用第三方SDK识别身份证后将图像保存到SD卡,同时将图像地址和其他信息一起传送到React Native JSX。
/** * JS和Native异步通信方式之Callback方法 */ @ReactMethod public void androidScanCallbackMethod(String scanType,Callback successcallback,Callback errorCallback) { try { localsuccesscallback = successcallback; localerrorcallback = errorCallback; nativeisType = "callback"; startScanEnginer(scanType); } catch (Exception e) { localerrorcallback.invoke(e.getMessage()); } } /** * Callback方式获取身份证正面信息 */ public void iDFrontCallBackValue() { IDCardResult result = IDCardManager.getInstance().getResult(); try { JSONObject json = new JSONObject(); String name = result.name;//姓名 json.put("name",name); String sex = result.sex;//性别 json.put("sex",sex); String nation = result.nation;//民族 json.put("nation",nation); String birth = result.birth;//生日 json.put("birth",birth); String address = result.address;//地址 json.put("address",address); String cardnum = result.cardnum;//身份证号 json.put("cardnum",cardnum); Bitmap cardIm = result.cardIm;//正面图 String picIDFront = saveImage(picIDFrontUrl,cardIm); json.put("cardImage",picIDFront); localsuccesscallback.invoke(json.toString()); } catch (JSONException e) { e.printStackTrace(); localerrorcallback.invoke(e.getMessage()); } } /** * JS和Native异步通信方式之Promise方法 */ @ReactMethod public void androidScanPromiseMethod(String scanType,Promise promise) { try { localPromise = promise; nativeisType = "promise"; startScanEnginer(scanType); } catch (Exception e) { localPromise.reject("1",e.getMessage()); } } /** * Promise方式获取身份证正面信息 */ public void iDFrontPromiseValue() { IDCardResult result = IDCardManager.getInstance().getResult(); WritableMap writableMap = new WritableNativeMap(); String name = result.name;//姓名 writableMap.putString("name",name); String sex = result.sex;//性别 writableMap.putString("sex",sex); String nation = result.nation;//民族 writableMap.putString("nation",nation); String birth = result.birth;//生日 writableMap.putString("birth",birth); String address = result.address;//地址 writableMap.putString("address",address); String cardnum = result.cardnum;//身份证号 writableMap.putString("cardnum",cardnum); Bitmap cardIm = result.cardIm;//正面图 String picIDFront = saveImage(picIDFrontUrl,cardIm); writableMap.putString("cardImage",picIDFront); localPromise.resolve(writableMap); } /** * 保存图片 */ public String saveImage(String filename,Bitmap bmp) { File file = null; // 首先保存图片 try { File appDir = new File(Environment.getExternalStorageDirectory(),"eds"); if (!appDir.exists()) { appDir.mkdir(); } Activity cur_activity = getCurrentActivity(); file = new File(appDir,filename); FileOutputStream fos = new FileOutputStream(file); bmp.compress(Bitmap.CompressFormat.JPEG,80,fos); fos.flush(); fos.close(); //其次把文件插入到系统图库 MediaStore.Images.Media.insertImage(cur_activity.getContentResolver(),file.getAbsolutePath(),filename,null); //最后通知图库更新 cur_activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.parse("file://" + file.getAbsolutePath()))); } catch (Exception e) { e.printStackTrace(); return e.getMessage(); } return file.getPath(); }
JSX端主要代码实现:
需要注意一点是图片获取的方式上不一样,初始化时是从APP中的res文件夹下获取的logo图片,
所有用的是 require('./res/img/logo.png'),而之后从原生中返回的图片是保存到SD卡中,
把图片地址返回来了,那显示图片时采用的是{uri: 'file://' + map.cardImage}。
var { NativeModules } = require("react-native"); module.exports = NativeModules.NativeExocr; this.state = { name: 'name',nation: 'nation',birth: 'birth',address: 'address',cardImage: require('./res/img/logo.png'),}; onPress() { //CallBack调用方式 // NativeExocr.androidScanCallbackMethod(NativeExocr.ID_FRONT_TYPE,(successcallback) => { // var json = JSON.parse(successcallback); // this.setState({ // szCardID: json.cardnum,// szName: json.name,// szSex: json.sex,// szNation: json.nation,// szClass: json.birth,// }); // },(errorcallback) => { // alert(errorcallback); // }); //Promise调用方式 NativeEscan.androidScanPromiseMethod(NativeExocr.ID_FRONT_TYPE).then((map) => { this.setState({ name: map.name,nation: map.nation,cardImage: { uri: 'file://' + map.cardImage },}) },(code,message) => { alert(message); }).catch((error) => { alert(error); }); } } render() { return ( <Image source={this.state.cardImage} style={styles.imagestyle}/> ); }