Expo(SDK42) React Native应用如何检测PROCESS_TEXT intent并获取传递文本
解决方案
你当前的Intent Filter配置是正确的,拿不到数据的核心原因是PROCESS_TEXT类型的Intent携带的文本数据存放在系统预置Extra字段中,Expo默认的Linking仅处理Uri格式的Intent数据,不会主动读取Extra内容,提供两种可行方案:
方案1:少量原生修改适配Linking(无需新增模块)
- 先恢复你之前移除的Linking配置,出现重复配置警告是因为你自定义的Intent Filter和Linking自动生成的配置存在重叠,只需要保留
app.json中expo.scheme字段为唯一值(比如myapp)即可解决警告。 - 打开安卓原生项目下的
MainActivity.java(路径:android/app/src/main/java/你的包名/MainActivity.java),修改代码如下:
import android.content.Intent; import android.os.Bundle; import android.net.Uri; // 新增导入 public class MainActivity extends ReactActivity { // 保留原有代码不变,新增以下方法 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handleProcessIntent(getIntent()); } @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); handleProcessIntent(intent); } private void handleProcessIntent(Intent intent) { if (Intent.ACTION_PROCESS_TEXT.equals(intent.getAction())) { String selectedText = intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT); if (selectedText != null) { // 将文本数据包装为自定义Scheme的Uri,适配Linking识别 Intent wrapIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("myapp://process?content=" + Uri.encode(selectedText))); setIntent(wrapIntent); } } } }
- JS层直接用Linking读取数据:
import * as Linking from 'expo-linking'; import { useEffect } from 'react'; useEffect(() => { // 处理冷启动场景 const getInitData = async () => { const initUrl = await Linking.getInitialURL(); if (initUrl?.startsWith('myapp://process')) { const { queryParams } = Linking.parse(initUrl); const targetText = queryParams.content; // 此处处理拿到的选中文本 console.log(targetText); } }; getInitData(); // 处理后台唤起场景 const linkListener = Linking.addEventListener('url', (e) => { if (e.url.startsWith('myapp://process')) { const { queryParams } = Linking.parse(e.url); const targetText = queryParams.content; console.log(targetText); } }); return () => linkListener?.remove(); }, []);
方案2:自定义原生模块读取(无需调整Linking配置)
如果你不想修改现有Linking配置,可以直接写一个极小的原生模块读取Intent数据:
- 新建安卓原生文件
android/app/src/main/java/你的包名/ProcessTextModule.java:
package com.yourpackage; // 替换为你的实际包名 import android.content.Intent; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Promise; public class ProcessTextModule extends ReactContextBaseJavaModule { public ProcessTextModule(ReactApplicationContext context) { super(context); } @Override public String getName() { return "ProcessTextModule"; } @ReactMethod public void getSelectedText(Promise promise) { Intent intent = getCurrentActivity().getIntent(); if (Intent.ACTION_PROCESS_TEXT.equals(intent.getAction())) { String text = intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT); promise.resolve(text); } else { promise.resolve(null); } } }
- 注册模块(在同目录下的
MainApplication.java的getPackages方法中添加模块实例即可,SDK42的bare工作流会自动识别也可手动注册) - JS层调用读取数据:
import { NativeModules, AppState } from 'react-native'; import { useEffect } from 'react'; const { ProcessTextModule } = NativeModules; useEffect(() => { // 启动时读取 const fetchText = async () => { const text = await ProcessTextModule.getSelectedText(); if (text) { // 处理文本 console.log(text); } }; fetchText(); // 可选:监听APP从后台切到前台时重新读取 const appStateListener = AppState.addEventListener('change', (state) => { if (state === 'active') fetchText(); }); return () => appStateListener?.remove(); }, []);
内容的提问来源于stack exchange,提问作者Fitter Man
相关产品推荐
相关产品推荐

