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

如何让React Native应用出现在分享面板建议并处理共享数据?

React Native 接收其他应用共享内容实现指南

要让你的React Native应用出现在系统分享面板并处理外部共享数据,需要分别完成iOS/Android平台的配置和JS层的数据监听与处理,以下是具体步骤:


一、配置应用使其显示在分享面板

1. iOS 平台配置

(1)修改Info.plist

打开项目的ios/[你的项目名]/Info.plist文件,添加以下配置以支持接收不同类型的共享内容(文本、图片、文件等):

<!-- 自定义URL Scheme,用于接收通过链接传递的共享数据 -->
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>myappshare</string> <!-- 替换成你的自定义Scheme,如appname-share -->
    </array>
  </dict>
</array>

<!-- 支持系统通用共享场景 -->
<key>NSUserActivityTypes</key>
<array>
  <string>com.apple.corespotlightitem</string>
</array>

<!-- 配置可接收的内容类型(示例:文本、图片) -->
<key>CFBundleDocumentTypes</key>
<array>
  <dict>
    <key>CFBundleTypeName</key>
    <string>Plain Text</string>
    <key>LSHandlerRank</key>
    <string>Alternate</string>
    <key>LSItemContentTypes</key>
    <array>
      <string>public.plain-text</string>
    </array>
  </dict>
  <dict>
    <key>CFBundleTypeName</key>
    <string>Image Files</string>
    <key>LSHandlerRank</key>
    <string>Alternate</string>
    <key>LSItemContentTypes</key>
    <array>
      <string>public.image</string>
    </array>
  </dict>
</array>

(2)处理AppDelegate中的共享回调

在AppDelegate.swift(或AppDelegate.m)中添加代码,捕获共享数据并通知JS层:

import UIKit
import React

@main
class AppDelegate: UIResponder, UIApplicationDelegate, RCTBridgeDelegate {
    var bridge: RCTBridge!
    var window: UIWindow?
    private var sharedData: [String: Any]?

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        // 解析URL中的共享参数
        let queryParams = url.queryParameters ?? [:]
        sharedData = queryParams
        notifyJSOfSharedData()
        return RCTLinkingManager.application(app, open: url, options: options)
    }

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        // 处理通用链接或系统共享的内容
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL {
            sharedData = ["type": "url", "content": url.absoluteString]
            notifyJSOfSharedData()
        }
        return RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
    }

    // 发送通知到JS层
    private func notifyJSOfSharedData() {
        guard let data = sharedData else { return }
        NotificationCenter.default.post(name: NSNotification.Name("SharedDataReceived"), object: data)
    }
}

// 扩展:解析URL参数
extension URL {
    var queryParameters: [String: String]? {
        guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true), let queryItems = components.queryItems else { return nil }
        return queryItems.reduce(into: [String: String]()) { (result, item) in
            result[item.name] = item.value
        }
    }
}

2. Android 平台配置

(1)修改AndroidManifest.xml

打开android/app/src/main/AndroidManifest.xml,在主Activity标签内添加intent-filter,声明应用可接收的共享类型:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
    android:launchMode="singleTask"
    android:windowSoftInputMode="adjustResize">

    <!-- 接收单条文本 -->
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>

    <!-- 接收单张图片 -->
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>

    <!-- 接收多张图片 -->
    <intent-filter>
        <action android:name="android.intent.action.SEND_MULTIPLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
</activity>

(2)在MainActivity中处理共享数据

在MainActivity.kt(或MainActivity.java)中捕获Intent中的共享数据,并发送到JS层:

import android.content.Intent
import android.net.Uri
import com.facebook.react.ReactActivity
import com.facebook.react.defaults.DefaultReactActivityDelegate
import com.facebook.react.modules.core.DeviceEventManagerModule

class MainActivity : ReactActivity() {
    private var sharedData: HashMap<String, Any>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        handleIncomingIntent(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleIncomingIntent(intent)
    }

    private fun handleIncomingIntent(intent: Intent?) {
        intent?.let {
            when (it.action) {
                Intent.ACTION_SEND -> {
                    val mimeType = it.type
                    when {
                        mimeType?.startsWith("text/") == true -> {
                            val text = it.getStringExtra(Intent.EXTRA_TEXT)
                            sharedData = hashMapOf("type" to "text", "content" to text)
                        }
                        mimeType?.startsWith("image/") == true -> {
                            val imageUri = it.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
                            imageUri?.let { uri ->
                                sharedData = hashMapOf("type" to "image", "uri" to uri.toString())
                            }
                        }
                    }
                    sharedData?.let { data -> sendDataToJS(data) }
                }
                Intent.ACTION_SEND_MULTIPLE -> {
                    val mimeType = it.type
                    if (mimeType?.startsWith("image/") == true) {
                        val imageUris = it.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
                        imageUris?.let { uris ->
                            val uriStrings = uris.map { it.toString() }
                            sharedData = hashMapOf("type" to "multiple_images", "uris" to uriStrings)
                            sendDataToJS(sharedData!!)
                        }
                    }
                }
            }
        }
    }

    // 发送数据到JS层
    private fun sendDataToJS(data: HashMap<String, Any>) {
        reactInstanceManager.currentReactContext?.let { context ->
            context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
                .emit("SharedDataReceived", data)
        }
    }

    override fun createReactActivityDelegate() = DefaultReactActivityDelegate(
        this,
        mainComponentName,
        fabricEnabled = false
    )
}

二、JS层监听并处理共享数据

在React Native的JS代码中,通过事件监听获取Native传递的共享数据:

import { useEffect, useState } from 'react';
import { View, Text, DeviceEventEmitter, Linking } from 'react-native';

const App = () => {
  const [sharedContent, setSharedContent] = useState(null);

  useEffect(() => {
    // 监听Android平台的共享事件
    const androidSubscription = DeviceEventEmitter.addListener(
      'SharedDataReceived',
      (data) => {
        setSharedContent(data);
        console.log('收到Android共享数据:', data);
        // 这里可以添加数据处理逻辑,比如存储、展示等
      }
    );

    // 监听iOS平台的URL跳转事件
    const iosSubscription = Linking.addEventListener('url', (event) => {
      const url = new URL(event.url);
      const params = Object.fromEntries(url.searchParams.entries());
      const data = { type: 'text', content: params.text || params.url };
      setSharedContent(data);
      console.log('收到iOS共享数据:', data);
    });

    // 检查应用启动时是否携带共享数据
    const checkInitialData = async () => {
      const initialUrl = await Linking.getInitialURL();
      if (initialUrl) {
        const url = new URL(initialUrl);
        const params = Object.fromEntries(url.searchParams.entries());
        setSharedContent({ type: 'text', content: params.text || params.url });
      }
    };

    checkInitialData();

    // 清理监听
    return () => {
      androidSubscription.remove();
      iosSubscription.remove();
    };
  }, []);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }}>
      {sharedContent ? (
        <Text style={{ fontSize: 16 }}>
          收到共享内容:\n{JSON.stringify(sharedContent, null, 2)}
        </Text>
      ) : (
        <Text style={{ fontSize: 16 }}>等待接收共享内容...</Text>
      )}
    </View>
  );
};

export default App;

关键注意事项

  • iOS平台:如果需要接收更多类型的文件,需在Info.plist中添加对应的UTI(统一类型标识符),可参考苹果官方的UTI列表。
  • Android平台:Android 10及以上版本处理文件URI时,需使用ContentResolver获取文件内容,避免直接访问路径导致权限问题。
  • 测试方法:打开相册、浏览器等应用,选择内容后点击分享,即可在面板中看到你的应用。

内容的提问来源于stack exchange,提问作者Leri Gogsadze

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:59:58