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

React Native Navigation v2跨App分享数据(Android/iOS)问题求助

解决React Native(react-native-navigation v2)跨平台接收分享数据问题

针对你遇到的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:09:52