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

Flutter中如何在应用被杀死后仍在后台运行定时器?

Flutter 应用关闭后触发定时通知的解决方案

Android 端处理

  • 调整WorkManager任务配置
    普通的OneTimeWorkRequest在应用被强行杀死后大概率失效,建议改用PeriodicWorkRequest配合宽松的触发约束,或者结合AlarmManager(适配Android 12及以下)+ WorkManager的组合方案——AlarmManager能在设备休眠时唤醒系统,保证任务触发。
    示例代码:
    // 初始化WorkManager
    void initWorkManager() {
      Workmanager().initialize(
        taskCallbackDispatcher,
        isInDebugMode: true,
      );
      // 注册定时任务,示例为1小时后触发,最小间隔需符合Android 15分钟限制
      Workmanager().registerPeriodicTask(
        "timer_notification",
        "send_notification",
        initialDelay: Duration(hours: 1),
        frequency: Duration(hours: 1),
        constraints: Constraints(
          networkType: NetworkType.not_required,
          requiresBatteryNotLow: false,
        ),
      );
    }
    
    // 任务回调函数
    void taskCallbackDispatcher() {
      Workmanager().executeTask((task, inputData) {
        triggerLocalNotification();
        return Future.value(true);
      });
    }
    
    // 本地通知发送逻辑
    void triggerLocalNotification() {
      // 这里接入flutter_local_notifications等库实现通知弹出
    }
    
  • 补充必要权限
    在AndroidManifest.xml中添加以下权限:
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
    
    Android 13+需动态申请POST_NOTIFICATIONS权限,确保通知能正常弹出。
  • 规避电池优化
    部分厂商的电池优化会直接杀死后台任务,需引导用户将应用加入白名单,可通过代码跳转系统设置:
    void requestBatteryOptimizationWhitelist() async {
      final AndroidIntent intent = AndroidIntent(
        action: "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS",
        data: "package:${await getPackageName()}",
      );
      await intent.launch();
    }
    

iOS 端处理

iOS对后台任务限制严格,WorkManager适配性有限,建议直接使用UNUserNotificationCenter结合系统定时触发器:

  • 配置通知权限(在AppDelegate.swift中添加):
    import UserNotifications
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
        return true
    }
    
  • Dart端触发定时通知:
    void scheduleTimedNotification(Duration delay) async {
      final FlutterLocalNotificationsPlugin notificationPlugin = FlutterLocalNotificationsPlugin();
      const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
        "timer_channel",
        "定时通知频道",
        importance: Importance.max,
        priority: Priority.high,
      );
      const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails);
      await notificationPlugin.schedule(
        0,
        "时间到了",
        "指定时长已结束",
        DateTime.now().add(delay),
        notificationDetails,
        androidAllowWhileIdle: true,
        uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
      );
    }
    
  • 后台模式配置:在Info.plist中添加UIBackgroundModes,包含remote-notification;注意iOS不支持长期后台定时任务,仅能通过系统通知触发器实现,只要用户授予通知权限,即使应用关闭,系统也会在指定时间触发通知。

常见排查点

  • Android端检查应用是否开启自启动权限,小米、华为等国产ROM默认关闭自启动,需用户手动开启。
  • 用Workmanager().getAllTasks()确认任务是否成功注册。
  • iOS端确保设备未开启低电量模式,该模式会延迟通知触发。

内容的提问来源于stack exchange,提问作者Ali Gomaa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:05:17