React Native與原生的圖片互動問題
阿新 • • 發佈:2019-02-11
專案中的一個需求:在原生系統中呼叫第三方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}/> ); }