React Native Navigation v2跨App分享数据(Android/iOS)问题求助
针对你遇到的Android端能唤起App但拿不到分享数据,以及iOS端不知道如何配置的问题,结合你的技术栈(react@16.6.3、react-native@0.57.8、react-native-navigation@2.6.0),给出以下针对性解决方案:
Android端:获取分享Intent数据
你已经配置了intent-filter能唤起App,但Linking组件仅适用于处理URL跳转类的ACTION_VIEW Intent,而分享的ACTION_SEND Intent数据需要从Intent的Extras中提取。另外由于你使用NavigationActivity,需要调整Native代码来将数据传递到RN层:
1. 修改MainActivity.java
替换你的MainActivity代码,导入必要包并通过DeviceEventManagerModule将分享数据发送到RN端:
package com.my.app; import com.imagepicker.permissions.OnImagePickerPermissionsCallback; import com.facebook.react.modules.core.PermissionListener; import com.reactnativenavigation.NavigationActivity; import android.content.Intent; import com.facebook.react.bridge.ReactContext; import com.facebook.react.modules.core.DeviceEventManagerModule; import android.os.Bundle; public class MainActivity extends NavigationActivity implements OnImagePickerPermissionsCallback { private PermissionListener listener; @Override public void setPermissionListener(PermissionListener listener) { this.listener = listener; } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (listener != null) { listener.onRequestPermissionsResult(requestCode, permissions, grantResults); } super.onRequestPermissionsResult(requestCode, permissions, grantResults); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 处理App启动时的初始分享Intent handleShareIntent(getIntent()); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // 处理App已启动时的新分享Intent handleShareIntent(intent); } private void handleShareIntent(Intent intent) { if (intent != null && Intent.ACTION_SEND.equals(intent.getAction())) { ReactContext reactContext = getReactInstanceManager().getCurrentReactContext(); if (reactContext != null) { // 提取分享数据:文本/URL或图片路径 String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); String sharedImageUri = intent.getStringExtra(Intent.EXTRA_STREAM); // 发送事件到RN端 reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("onShareReceived", new Bundle() {{ putString("text", sharedText); putString("imageUri", sharedImageUri); }}); } } } }
2. RN端监听分享事件
在Home组件(或根组件)中,监听Native发送的onShareReceived事件,替换之前的Linking相关代码:
import { NativeEventEmitter, NativeModules } from 'react-native'; class Home extends Component { componentDidMount() { // 创建事件监听器 const shareEventEmitter = new NativeEventEmitter(NativeModules.RNEventEmitter); this.shareSubscription = shareEventEmitter.addListener( 'onShareReceived', (data) => { console.log('收到分享数据:', data); // 处理文本/URL或图片 if (data.text) { console.log('分享的文本/URL:', data.text); } if (data.imageUri) { console.log('分享的图片URI:', data.imageUri); } } ); } componentWillUnmount() { // 移除监听器防止内存泄漏 this.shareSubscription.remove(); } // ...其他组件逻辑 }
iOS端:配置分享接收与数据获取
iOS没有Android的intent-filter,需要通过Info.plist配置让App出现在分享列表,并修改AppDelegate来传递数据到RN端:
1. 配置Info.plist
在Info.plist中添加以下配置,让App支持接收文本/URL和图片类型的分享:
<key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeName</key> <string>Shared Content</string> <key>LSHandlerRank</key> <string>Alternate</string> <key>LSItemContentTypes</key> <array> <string>public.url</string> <string>public.text</string> <string>public.image</string> </array> </dict> </array>
2. 修改AppDelegate.m
在AppDelegate中添加处理分享数据的逻辑,并发送事件到RN端:
#import "AppDelegate.h" #import <React/RCTBridge.h> #import <React/RCTBundleURLProvider.h> #import <React/RCTRootView.h> #import <React/RCTNativeModule.h> #import <React/RCTEventEmitter.h> @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // ...原有代码 // 处理启动时的分享数据 [self handleShareDataFromOptions:launchOptions]; return YES; } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { // 处理URL类型的分享 [self sendShareEventToRN:@{@"text": url.absoluteString}]; return YES; } - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler { // 处理通用链接或分享数据 if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { NSURL *url = userActivity.webpageURL; [self sendShareEventToRN:@{@"text": url.absoluteString}]; } return YES; } - (void)handleShareDataFromOptions:(NSDictionary *)launchOptions { // 处理从分享启动的情况 NSURL *url = launchOptions[UIApplicationLaunchOptionsURLKey]; if (url) { [self sendShareEventToRN:@{@"text": url.absoluteString}]; } } - (void)sendShareEventToRN:(NSDictionary *)data { RCTBridge *bridge = [self.reactNativeNavigation getBridge]; if (bridge && bridge.isValid) { [[bridge eventDispatcher] sendAppEventWithName:@"onShareReceived" body:data]; } } @end
3. RN端监听事件(同Android)
iOS端的RN监听代码和Android端完全一致,复用之前的NativeEventEmitter监听逻辑即可。
注意事项
- Android测试时,需分别测试App从冷启动、后台唤起两种场景下的分享接收
- iOS端分享功能需在真机上测试,模拟器无法完整模拟跨App分享流程
- 若需支持多文件分享,可扩展Native代码中的Intent/NSUserActivity处理逻辑
内容的提问来源于stack exchange,提问作者Jojo
相关产品推荐
相关产品推荐

