You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何实现Android Intent调用及onActivityResult结果回调?

React Native中如何实现Android Intent调用及onActivityResult结果回调?

刚好我之前帮团队处理过类似的React Native迁移需求,把你原来Android原生的Intent调用+onActivityResult回调逻辑转到RN里,主要有两种可行思路:用成熟的第三方库快速落地,或者自己写原生模块做定制化处理,我结合你的业务场景给你详细拆解:


一、用第三方库快速实现(推荐优先尝试)

如果你的需求没有特别复杂的定制化,用react-native-intent-launcher-next这类封装好的库最省心,它已经帮你处理了Intent调用和结果回调的原生逻辑,直接在RN层调用即可。

步骤1:安装依赖

# npm
npm install react-native-intent-launcher-next --save

# 或者yarn
yarn add react-native-intent-launcher-next

RN 0.60+版本会自动完成原生链接,不用额外操作。

步骤2:对应你的业务场景写RN代码

把你原来Java里的按钮点击、Intent参数构造、结果处理逻辑转成RN代码:

import React, { useState } from 'react';
import { View, TextInput, Button, Alert, Console } from 'react-native';
import IntentLauncher from 'react-native-intent-launcher-next';

// 定义请求码,和原生保持一致
const TRANS_PAY_CARD = 1;

const CardPaymentScreen = () => {
  const [edtAmount, setEdtAmount] = useState('');

  // 卡片支付按钮点击事件
  const handleCardPayment = async () => {
    try {
      // 解析金额(和原生逻辑一致)
      const amount = parseInt(edtAmount.trim());
      if (isNaN(amount)) {
        Alert.alert('错误', '请输入有效的金额');
        return;
      }

      // 构造交易数据JSON字符串
      const transactionData = JSON.stringify({
        paymentType: 'CARD',
        amount: amount
      });

      // 构造Intent参数
      const intentOptions = {
        action: 'com.awesomebank.paymentapp', // 和原生的Action一致
        extras: {
          version: '1.3.15',
          transactionType: 'PAYMENT',
          transactionData: transactionData
        }
      };

      // 调用startActivityForResult,等待返回结果
      const result = await IntentLauncher.startActivityForResult(intentOptions, TRANS_PAY_CARD);

      // 处理银行App返回的结果(对应原生的onActivityResult)
      if (result.requestCode === TRANS_PAY_CARD) {
        const { result: transResult, resultMsg, transData } = result.extras;
        console.log('交易结果:', transResult, resultMsg, transData);
        
        // 这里写你原来的交易结果处理逻辑,比如更新订单状态、显示成功提示
        if (transResult === 'SUCCESS') {
          Alert.alert('支付成功', resultMsg);
        } else {
          Alert.alert('支付失败', resultMsg);
        }
      }
    } catch (error) {
      // 捕获异常:比如JSON解析失败、银行App未安装、Intent调用失败等
      Alert.alert('错误', error.message || '支付请求失败');
    }
  };

  return (
    <View style={{ padding: 20 }}>
      <TextInput
        placeholder="请输入金额"
        keyboardType="numeric"
        value={edtAmount}
        onChangeText={setEdtAmount}
        style={{ borderBottomWidth: 1, marginBottom: 20, padding: 10 }}
      />
      <Button title="卡片支付" onPress={handleCardPayment} />
    </View>
  );
};

export default CardPaymentScreen;

二、自定义原生模块(适合定制化需求)

如果第三方库的封装满足不了你的特殊需求(比如要处理复杂的Intent Flags、自定义参数解析),可以自己写Android原生模块,暴露给RN调用,完全复刻你原来的原生逻辑。

步骤1:编写Android原生模块

在你的RN项目的android/app/src/main/java/[你的项目包名]/目录下,创建两个文件:

1. IntentModule.java(核心逻辑,处理Intent和结果回调)

package com.yourprojectname; // 替换成你的项目包名

import android.app.Activity;
import android.content.Intent;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.BaseActivityEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;

public class IntentModule extends ReactContextBaseJavaModule {
  // 和原生一致的请求码
  private static final int TRANS_PAY_CARD = 1;
  // 用来传递回调结果的Promise
  private Promise activityResultPromise;

  // 监听Activity结果的回调
  private final ActivityEventListener activityEventListener = new BaseActivityEventListener() {
    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
      if (requestCode == TRANS_PAY_CARD && activityResultPromise != null) {
        if (resultCode == Activity.RESULT_OK && data != null) {
          // 把银行App返回的结果转成RN能识别的WritableMap
          WritableMap resultMap = new WritableNativeMap();
          resultMap.putString("result", data.getStringExtra("result"));
          resultMap.putString("resultMsg", data.getStringExtra("resultMsg"));
          resultMap.putString("transData", data.getStringExtra("transData"));
          // 把结果返回给RN
          activityResultPromise.resolve(resultMap);
        } else {
          // 处理失败或取消的情况
          activityResultPromise.reject("TRANS_FAILED", "交易取消或失败");
        }
        // 清空Promise,避免内存泄漏
        activityResultPromise = null;
      }
    }
  };

  public IntentModule(ReactApplicationContext reactContext) {
    super(reactContext);
    // 注册Activity事件监听
    reactContext.addActivityEventListener(activityEventListener);
  }

  // 模块名称,RN端通过这个名称调用
  @Override
  public String getName() {
    return "IntentModule";
  }

  // 暴露给RN的方法:启动卡片支付的Intent
  @ReactMethod
  public void startCardPayment(ReadableMap params, Promise promise) {
    Activity currentActivity = getCurrentActivity();
    if (currentActivity == null) {
      promise.reject("NO_ACTIVITY", "当前Activity为空");
      return;
    }

    activityResultPromise = promise;
    // 构造Intent(和你原来的Java代码逻辑完全一致)
    Intent cardPaymentIntent = new Intent();
    cardPaymentIntent.setAction(params.getString("action"));
    // 传入参数
    cardPaymentIntent.putExtra("version", params.getString("version"));
    cardPaymentIntent.putExtra("transactionType", params.getString("transactionType"));
    cardPaymentIntent.putExtra("transactionData", params.getString("transactionData"));
    // 启动Intent并等待结果
    currentActivity.startActivityForResult(cardPaymentIntent, TRANS_PAY_CARD);
  }
}

2. IntentPackage.java(注册原生模块到RN)

package com.yourprojectname; // 替换成你的项目包名

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class IntentPackage implements ReactPackage {
  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    modules.add(new IntentModule(reactContext));
    return modules;
  }

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }
}

步骤2:在RN项目中注册原生模块

打开android/app/src/main/java/[你的项目包名]/MainApplication.java,在getPackages()方法里添加我们的自定义Package:

@Override
protected List<ReactPackage> getPackages() {
  @SuppressWarnings("UnnecessaryLocalVariable")
  List<ReactPackage> packages = new PackageList(this).getPackages();
  // 加入自定义的IntentPackage
  packages.add(new IntentPackage());
  return packages;
}

步骤3:RN端调用原生模块

import React, { useState } from 'react';
import { View, TextInput, Button, Alert, NativeModules } from 'react-native';

// 引入我们自定义的原生模块
const { IntentModule } = NativeModules;

const CardPaymentScreen = () => {
  const [edtAmount, setEdtAmount] = useState('');

  const handleCardPayment = async () => {
    try {
      const amount = parseInt(edtAmount.trim());
      if (isNaN(amount)) {
        Alert.alert('错误', '请输入有效的金额');
        return;
      }

      const transactionData = JSON.stringify({
        paymentType: 'CARD',
        amount: amount
      });

      // 构造传给原生模块的参数
      const params = {
        action: 'com.awesomebank.paymentapp',
        version: '1.3.15',
        transactionType: 'PAYMENT',
        transactionData: transactionData
      };

      // 调用原生模块的方法,等待返回结果
      const result = await IntentModule.startCardPayment(params);
      
      // 处理返回结果
      console.log('交易结果:', result.result, result.resultMsg, result.transData);
      if (result.result === 'SUCCESS') {
        Alert.alert('支付成功', result.resultMsg);
      } else {
        Alert.alert('支付失败', result.resultMsg);
      }
    } catch (error) {
      Alert.alert('错误', error.message || '支付请求失败');
    }
  };

  return (
    <View style={{ padding: 20 }}>
      <TextInput
        placeholder="请输入金额"
        keyboardType="numeric"
        value={edtAmount}
        onChangeText={setEdtAmount}
        style={{ borderBottomWidth: 1, marginBottom: 20, padding: 10 }}
      />
      <Button title="卡片支付" onPress={handleCardPayment} />
    </View>
  );
};

export default CardPaymentScreen;

一些注意事项

  1. 异常处理:一定要捕获调用过程中的异常,比如银行App未安装、金额解析失败、JSON格式错误等,给用户友好提示。
  2. 参数一致性:传递给Intent的参数(比如action、transactionData)要和你原来的Java代码完全一致,否则银行App可能无法识别。
  3. 权限检查:如果你的业务需要特殊权限(比如读取设备信息),要在AndroidManifest.xml中声明,并在RN端做权限申请。
  4. RN版本兼容:如果是RN 0.70+,原生的startActivityForResult已经被ActivityResultContracts替代,但银行App用旧的方式返回结果的话,旧的API依然可以正常工作;如果要适配新API,可以在原生模块里改成用registerForActivityResult。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 13:33:08