1. 程式人生 > >React Native與原生的圖片互動問題

React Native與原生的圖片互動問題

專案中的一個需求:在原生系統中呼叫第三方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}/>
    );
}