简体   繁体   中英

Calling Native modules from android and send events from this module to React Native

I'm trying to implement a solution to use React-Native to calls "pagseguro" SDK in reason to make payments.

I've already done and got all process using Native Modules with React Native, and it works pretty well, but in the middle of transactions, there is a listener that sends message to guide user how to proceed (message like: "put your credit card" and etc..), so I try to call RCTDeviceEventEmitter to send this message to JS and show to user but, it's sended all only in the final of operation and not in real time when they are created.

My JS Code:

 state = {
    calling: "",
    error: ""
  };

  onPress = () => {
    // const request = {
    //   paymentType: RNPlugPag.PAYMENT_CREDIT,
    //   installments: 5,
    //   code: "RNPlugPag",
    //   amount: "123,45"
    // };
    NativeModules.RNBPlugPag.doCreditPayment(
      error => {
        this.setState({ calling: error });
      },
      response => {
        this.setState({ calling: response });
      }
    );

    // alert(response);
  };

  componentDidMount = () => {
    const teste = new NativeEventEmitter(NativeModules.RNBPlugPag);
    teste.addListener("paymentEvent", event => this.setState({ error: event }));
    // DeviceEventEmitter.addListener("paymentEvent", event =>
    //   this.setState({ error: event })
    // );
  };

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <TouchableOpacity
          onPress={() => this.onPress()}
          style={{
            backgroundColor: "blue",
            width: 120,
            height: 60,
            justifyContent: "center",
            alignItems: "center"
          }}
        >
          <Text style={{ fontSize: 20, color: "yellow" }}>Clique</Text>
        </TouchableOpacity>
        <Text style={{ fontSize: 20 }}>{this.state.calling}</Text>
        <Text style={{ fontSize: 20 }}>{this.state.error}</Text>
      </View>

My Java Code:

 @ReactMethod
    public void doCreditPayment(Callback error, Callback response) {
        try {
            // WritableMap map = Arguments.createMap();

            PlugPagPaymentData paymentData = new PlugPagPaymentData(PlugPag.TYPE_CREDITO, 110,
                    PlugPag.INSTALLMENT_TYPE_A_VISTA, 1, "APPDEMO");

            PlugPagAppIdentification appIdentification = new PlugPagAppIdentification("MeuApp", "1.0.7");

            PlugPag plugpag = new PlugPag(reactContext, appIdentification);

            PlugPagInitializationResult result = plugpag
                    .initializeAndActivatePinpad(new PlugPagActivationData("403938"));

            if (result.getResult() == PlugPag.RET_OK) {

                plugpag.setEventListener(plugPagEventData -> {

                    emitDeviceEvent(plugPagEventData.getCustomMessage());

                });


                PlugPagTransactionResult transResult = plugpag.doPayment(paymentData);

                if (transResult.getResult() == PlugPag.RET_OK) {
                    response.invoke(transResult.getTransactionCode());
                } else {
                    error.invoke(transResult.getMessage());
                }

                // Log.i("GET", "GET " + transResult);

            } else {
                error.invoke(RETURN_ERROR);
            }


        } catch (IllegalViewOperationException e) {
            error.invoke(E_LAYOUT_ERROR);
        }

    }

    private void emitDeviceEvent(String message) {
        Log.i("GET", "GET " + message);
        // A method for emitting from the native side to JS
        // https://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("paymentEvent", message);
    }

I want to when I set the "plugpag.setEventListener" method and it sends messages to "emitDeviceEvent" , it automatically send to my JS listener and update the state even if the whole operation in "doCreditPayment" is not finished yet

You dont need to set callback error and response parameters, you can directly add event listener to your if else statements

> @ReactMethod
>     public void doCreditPayment() {
>         try {
>             // WritableMap map = Arguments.createMap();
> 
>             PlugPagPaymentData paymentData = new PlugPagPaymentData(PlugPag.TYPE_CREDITO, 110,
>                     PlugPag.INSTALLMENT_TYPE_A_VISTA, 1, "APPDEMO");
> 
>             PlugPagAppIdentification appIdentification = new PlugPagAppIdentification("MeuApp", "1.0.7");
> 
>             PlugPag plugpag = new PlugPag(reactContext, appIdentification);
> 
>             PlugPagInitializationResult result = plugpag
>                     .initializeAndActivatePinpad(new PlugPagActivationData("403938"));
> 
>             if (result.getResult() == PlugPag.RET_OK) {
> 
>                 plugpag.setEventListener(plugPagEventData -> {
>                    // you can add another listener here
                   }
> 
> 
>                 PlugPagTransactionResult transResult = plugpag.doPayment(paymentData);
> 
>                 if (transResult.getResult() == PlugPag.RET_OK) {
>                     //response.invoke(transResult.getTransactionCode());
>                     emitDeviceEvent("SuccessPayment", transResult.getTransactionCode());
> 
>                 });
>                 } else {
>                     //error.invoke(transResult.getMessage());
>                     emitDeviceEvent("ErrorPayment", transResult.getMessage());
> 
>                 });
>                 }
> 
>                 // Log.i("GET", "GET " + transResult);
> 
>             } else {
>                 error.invoke(RETURN_ERROR);
>             }
> 
> 
>         } catch (IllegalViewOperationException e) {
>             error.invoke(E_LAYOUT_ERROR);
>         }
> 
>     }
> 
>     private void emitDeviceEvent(String eventName, String message) {
>         Log.i("GET", "GET " + message);
>         // A method for emitting from the native side to JS
>         // https://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
>         reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName,
> message);
>     }

and to your react-native part

 onPress = () => {

    NativeModules.RNBPlugPag.doCreditPayment()   

};

  componentDidMount = () => {
    //const teste = new NativeEventEmitter(NativeModules.RNBPlugPag);
   // teste.addListener("SuccessPayment", event => this.setState({ error: event //}));
     DeviceEventEmitter.addListener("SuccessPayment", event =>
       this.setState({ success: event })
     );

     DeviceEventEmitter.addListener("ErrorPayment", event =>
       this.setState({ error: event })
     );   };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM