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

Expo(SDK42) React Native应用如何检测PROCESS_TEXT intent并获取传递文本

解决方案

你当前的Intent Filter配置是正确的,拿不到数据的核心原因是PROCESS_TEXT类型的Intent携带的文本数据存放在系统预置Extra字段中,Expo默认的Linking仅处理Uri格式的Intent数据,不会主动读取Extra内容,提供两种可行方案:

方案1:少量原生修改适配Linking(无需新增模块)

  1. 先恢复你之前移除的Linking配置,出现重复配置警告是因为你自定义的Intent Filter和Linking自动生成的配置存在重叠,只需要保留app.json中expo.scheme字段为唯一值(比如myapp)即可解决警告。
  2. 打开安卓原生项目下的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);
      }
    }
  }
}
  1. 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数据:

  1. 新建安卓原生文件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);
    }
  }
}
  1. 注册模块(在同目录下的MainApplication.java的getPackages方法中添加模块实例即可,SDK42的bare工作流会自动识别也可手动注册)
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:18:02