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

Flutter应用关闭时如何接收SMS消息?已试Telephony包无效

解决Flutter Telephony包后台接收SMS的问题

要让应用在未运行时也能后台接收SMS,得针对Android和iOS的平台特性分别配置,同时注意Telephony包的回调规则,以下是具体方案:

一、先搞懂后台回调的硬性要求

  • onBackgroundMessage必须是顶级函数或者静态函数,不能是类的成员函数(你的代码里已经写了顶级函数,但要确保它不依赖任何Flutter上下文或类成员变量)
  • 后台回调里不能做依赖Flutter引擎的操作(比如setState),只能做轻量处理:打印日志、写入本地存储、发送本地通知等

二、Android平台关键配置

1. 权限与清单配置

在android/app/src/main/AndroidManifest.xml里添加:

<!-- 基础短信权限 -->
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<!-- 后台服务必要权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Android 12+ 通知权限 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<application ...>
  <!-- 注册Telephony的短信广播接收器 -->
  <receiver
      android:name="com.shahxad.telephony.SmsReceiver"
      android:exported="true">
      <intent-filter>
          <action android:name="android.provider.Telephony.SMS_RECEIVED" />
      </intent-filter>
  </receiver>
</application>

2. 豁免电池优化

Android系统会自动杀死后台耗电应用,必须引导用户把你的应用加入电池优化白名单,代码里可以直接触发申请:

await telephony.requestIgnoreBatteryOptimizations();

三、iOS平台限制与配置

iOS的后台机制更严格,应用被完全杀死后基本无法接收SMS,仅在挂起状态下有有限支持,配置如下:

  1. 在ios/Runner/Info.plist添加权限说明:
<key>NSSMSUsageDescription</key>
<string>需要访问短信权限来接收消息</string>
  1. 在Xcode中开启后台模式:
    • 打开项目Runner -> Signing & Capabilities -> 添加Background Modes
    • 勾选"Remote notifications"(iOS需要这个权限支持后台唤醒)

四、修正后的完整代码示例

// 必须是顶级函数,不能放在类内部
void onBackgroundMessage(SmsMessage message) {
  // 后台只能做轻量操作,比如打印、发本地通知
  print("onBackgroundMessage: ${message.body}");
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _message = "";
  final telephony = Telephony.instance;

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  void onMessage(SmsMessage message) {
    setState(() {
      _message = message.body ?? "读取消息内容失败";
    });
  }

  Future<void> initPlatformState() async {
    // 请求短信和电话权限
    final bool? permissionsGranted = await telephony.requestPhoneAndSmsPermissions;
    if (permissionsGranted != null && permissionsGranted) {
      // 请求Android电池优化豁免
      await telephony.requestIgnoreBatteryOptimizations();
      // 开启短信监听
      telephony.listenIncomingSms(
        onNewMessage: onMessage,
        onBackgroundMessage: onBackgroundMessage,
        listenInBackground: true,
      );
    }

    if (!mounted) return;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("短信接收器")),
        body: Center(child: Text("收到的消息: $_message")),
      ),
    );
  }
}

五、常见排查点

  • 测试时不要用模拟器,部分模拟器不支持真实SMS接收
  • Android上务必确认应用在电池优化白名单内,否则后台进程会被系统杀死
  • 检查onBackgroundMessage里有没有调用Flutter相关API(比如setState),这些操作在后台会失效

内容的提问来源于stack exchange,提问作者Harsh Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:15:43