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

求助:基于Expo的React Native应用实现短信读取功能

在Expo React Native应用中实现短信读取与监听的可行方案

由于Expo Managed Workflow对原生模块的限制,你尝试的第三方库大多无法直接兼容。下面分两种场景给出可行方案:

一、完整功能实现(需转为Expo Bare Workflow)

如果必须读取历史短信并监听所有新短信,只能转为Bare Workflow,因为Managed模式下没有官方支持的短信读取API。

1. 转Bare Workflow

执行命令完成转换:

expo prebuild

2. 配置权限

在android/app/src/main/AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />

3. 读取特定号码的历史短信

使用适配RN 0.70+版本的react-native-get-sms-android,先动态申请权限再读取:

import { PermissionsAndroid } from 'react-native';
import SmsAndroid from 'react-native-get-sms-android';

// 请求短信读取权限
const requestSmsPermission = async () => {
  const granted = await PermissionsAndroid.request(
    PermissionsAndroid.PERMISSIONS.READ_SMS,
    {
      title: '短信读取权限',
      message: '应用需要读取指定号码的短信内容',
      buttonPositive: '允许',
      buttonNegative: '取消',
    },
  );
  return granted === PermissionsAndroid.RESULTS.GRANTED;
};

// 读取指定号码的短信
const fetchTargetSms = async (targetNumber) => {
  const hasPermission = await requestSmsPermission();
  if (!hasPermission) return [];

  return new Promise((resolve, reject) => {
    SmsAndroid.list(
      JSON.stringify({
        box: 'inbox', // 读取收件箱
        address: targetNumber, // 目标号码
        maxCount: 50, // 最多读取50条
      }),
      (err) => reject(err),
      (count, smsList) => {
        const parsedSms = JSON.parse(smsList);
        // 整理短信数据
        const formattedSms = parsedSms.map(sms => ({
          id: sms._id,
          address: sms.address,
          body: sms.body,
          date: new Date(parseInt(sms.date)),
        }));
        resolve(formattedSms);
      },
    );
  });
};

4. 监听新短信接收

通过原生事件监听短信广播:

import { NativeEventEmitter, NativeModules } from 'react-native';

const { SmsReceiver } = NativeModules;
const smsEventEmitter = new NativeEventEmitter(SmsReceiver);

// 启动短信监听
const startSmsListener = (targetNumber, onSmsReceived) => {
  const subscription = smsEventEmitter.addListener('onSmsReceived', (smsData) => {
    // 过滤目标号码的短信
    if (smsData.address === targetNumber) {
      onSmsReceived({
        address: smsData.address,
        body: smsData.body,
        date: new Date(),
      });
    }
  });

  // 触发原生监听逻辑
  SmsReceiver.startSmsListener();

  // 返回订阅实例,用于组件卸载时取消监听
  return subscription;
};

// 组件内使用示例
// useEffect(() => {
//   const sub = startSmsListener('10086', (sms) => {
//     console.log('收到目标号码短信:', sms);
//     // 更新应用内短信列表
//   });
//   return () => sub.remove();
// }, []);

二、验证码场景折中方案(Expo Managed Workflow可用)

如果你的需求仅为验证码自动填充(而非读取所有历史短信),可以使用Expo官方的expo-sms-retriever,无需转Bare:

1. 安装依赖

npx expo install expo-sms-retriever

2. 监听验证码短信

import * as SMSRetriever from 'expo-sms-retriever';

const setupSmsVerification = async () => {
  try {
    // 启动短信监听
    const isRegistered = await SMSRetriever.startSmsRetriever();
    if (!isRegistered) {
      console.log('短信监听启动失败');
      return;
    }

    // 监听短信接收事件
    const subscription = SMSRetriever.addSmsListener((event) => {
      // 从短信内容中提取6位验证码(可根据实际格式调整正则)
      const verificationCode = event.message.match(/\d{6}/)?.[0];
      if (verificationCode) {
        console.log('提取到验证码:', verificationCode);
        // 自动填充到输入框
      }
    });

    // 组件卸载时取消监听
    // return () => subscription.remove();
  } catch (error) {
    console.error('验证码监听出错:', error);
  }
};

注意:该方案仅支持符合Google规范的验证码短信(短信需包含应用签名,格式如【你的应用名】验证码123456),且无法读取历史短信。

关键注意事项

  • iOS平台:App Store审核严格限制短信读取权限,非验证码场景的权限申请几乎不会通过,仅推荐使用验证码自动填充方案。
  • Android平台:从API 29(Android 10)开始,动态申请权限时必须明确说明用途,否则用户可能拒绝授权。

内容的提问来源于stack exchange,提问作者Mohsen Ghadimpour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:43:11