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

Telephony包后台短信监听功能失效问题求助

Flutter后台监听短信失效问题解决方案

核心问题分析

你当前的实现把短信监听器注册在了Workmanager的一次性任务里,而Workmanager的executeTask执行完毕返回true后,整个任务进程会被系统销毁,导致监听器无法持续工作,这是核心原因。

分步解决方法

  1. 调整监听器注册时机
    直接在应用初始化阶段注册后台短信监听器,不要依赖Workmanager的一次性任务:

    // 必须是顶级函数,确保后台可调用
    void backgrounMessageHandler(SmsMessage message) {
      print(message.body);
    }
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      
      // 初始化telephony并注册后台监听器
      Telephony telephony = Telephony.backgroundInstance;
      await telephony.requestSmsPermissions;
      telephony.listenIncomingSms(
        onNewMessage: backgrounMessageHandler,
        onBackgroundMessage: backgrounMessageHandler,
        listenInBackground: true, // 明确开启后台监听模式
      );
    
      runApp(const MyApp());
    }
    
  2. 补全Android配置
    在android/app/src/main/AndroidManifest.xml中添加必要权限和广播接收器:

    <!-- 短信相关权限 -->
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <!-- Android 13+ 需要通知权限 -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    
    <!-- 注册telephony内置的短信广播接收器 -->
    <receiver
        android:name="com.shounakmulay.telephony.sms.IncomingSmsReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>
    
  3. 处理安卓后台限制

    • 对于Android 12及以上,需要动态申请POST_NOTIFICATIONS权限,否则后台监听可能被系统拦截。
    • 国产厂商(小米、华为等)有严格的后台管控,需要引导用户手动开启应用的「后台运行权限」和「忽略电池优化」:
      import 'package:android_intent_plus/android_intent.dart';
      import 'package:package_info_plus/package_info_plus.dart';
      
      void requestBatteryOptimizationExemption() async {
        final packageInfo = await PackageInfo.fromPackageInfo();
        final intent = AndroidIntent(
          action: 'android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS',
          data: 'package:${packageInfo.packageName}',
        );
        await intent.launch();
      }
      
  4. Workmanager的正确使用场景
    如果需要定时执行短信相关的辅助任务(比如批量同步未读短信),可以用Workmanager注册周期性任务,但不要用它来注册持续监听器:

    @pragma('vm:entry-point')
    void smsTaskDispatcher() {
      bg.Workmanager().executeTask((taskName, inputData) async {
        // 这里写周期性任务逻辑,比如检查未读短信
        return Future.value(true);
      });
    }
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      
      // 初始化Workmanager用于周期性任务
      await bg.Workmanager().initialize(smsTaskDispatcher, isInDebugMode: true);
      await bg.Workmanager().registerPeriodicTask(
        'sms-sync-task',
        'smsSync',
        frequency: const Duration(minutes: 15),
      );
    
      // 单独注册短信监听器
      Telephony telephony = Telephony.backgroundInstance;
      await telephony.requestSmsPermissions;
      telephony.listenIncomingSms(
        onNewMessage: backgrounMessageHandler,
        onBackgroundMessage: backgrounMessageHandler,
        listenInBackground: true,
      );
    
      runApp(const MyApp());
    }
    

重要注意事项

  • onBackgroundMessage必须是顶级函数或静态函数,不能是类的成员方法,否则后台进程无法调用。
  • 测试后台监听时,不要用热重载,需要完全重启应用后切换到后台测试。
  • 部分安卓机型需要手动开启「允许应用在后台弹出通知」,避免监听器被系统静默杀死。

内容的提问来源于stack exchange,提问作者Parham Khoshravesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:45:50