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

