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

Flutter应用完全关闭时如何显示本地通知(无需Firebase)

解决方案:无需Firebase实现应用完全关闭后的定时任务与通知

针对Android平台

WorkManager本身支持应用关闭后的任务执行,你遇到的问题可通过以下方式修复:

  • 确保初始化时机正确:在Android原生MainApplication的onCreate方法中初始化WorkManager,而非仅在Flutter页面初始化,保证应用首次启动就完成任务注册:
    override fun onCreate() {
        super.onCreate()
        WorkManager.initialize(this, Configuration.Builder().build())
        // 此处可提前调度周期性任务
    }
    
  • 规避系统后台限制:国产ROM(小米、华为等)存在严格的后台管控,需引导用户将应用加入后台白名单,可通过代码跳转至电池优化设置页:
    val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
    intent.data = Uri.parse("package:" + packageName)
    startActivity(intent)
    
  • 正确配置周期性任务:设置persist: true保证设备重启后任务不丢失,同时遵循Android最短15分钟的周期限制:
    final periodicTask = PeriodicWorkRequest(
      myTask,
      repeatInterval: Duration(hours: 24),
      initialDelay: Duration(minutes: 1),
      constraints: Constraints(networkType: NetworkType.none),
    );
    await Workmanager().registerPeriodicTask(
      'daily_db_check',
      'dailyTask',
      existingWorkPolicy: ExistingWorkPolicy.replace,
      persist: true,
    );
    

针对iOS平台

iOS后台执行机制更严格,需依赖BGTaskScheduler配合WorkManager实现:

  • 配置后台权限:在Xcode的Signing & Capabilities中添加Background Modes,勾选Background fetch和Background processing,或直接在Info.plist中添加UIBackgroundModes数组包含对应项。
  • 原生侧注册任务:在AppDelegate中完成后台任务的注册与调度,确保应用启动时就完成配置:
    import UIKit
    import Flutter
    import workmanager
    import BackgroundTasks
    
    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        WorkmanagerPlugin.registerTask(withIdentifier: "dailyTask")
        BGTaskScheduler.shared.register(forTaskWithIdentifier: "dailyTask", using: nil) { task in
            self.handleBackgroundTask(task: task as! BGAppRefreshTask)
        }
        self.scheduleNextTask()
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
      
      func handleBackgroundTask(task: BGAppRefreshTask) {
          WorkmanagerPlugin.sharedPlugin?.executeTask(withIdentifier: "dailyTask", input: nil, completionHandler: { success in
              task.setTaskCompleted(success: success)
          })
          self.scheduleNextTask()
      }
      
      func scheduleNextTask() {
          let request = BGAppRefreshTaskRequest(identifier: "dailyTask")
          request.earliestBeginDate = Date(timeIntervalSinceNow: 24*60*60)
          do {
              try BGTaskScheduler.shared.submit(request)
          } catch {
              print("调度任务失败: \(error)")
          }
      }
    }
    
  • 注意iOS限制:iOS无法保证任务精确执行,系统会根据设备电量、使用场景调度,应用完全关闭后仅在系统允许后台唤醒时触发任务。

跨平台通用要点

  • 数据库路径正确性:后台任务中访问sqflite时,使用绝对路径初始化数据库,避免上下文差异导致的路径错误:
    final dbPath = await getDatabasesPath();
    final database = await openDatabase(join(dbPath, 'your_db.db'));
    
  • 通知权限与渠道配置:Android 8.0+需提前创建通知渠道,iOS需主动请求通知权限,确保后台能正常展示通知:
    if (Platform.isAndroid) {
      const AndroidNotificationChannel channel = AndroidNotificationChannel(
        'daily_alert_channel',
        '每日提醒',
        description: '数据库检查结果通知',
        importance: Importance.high,
      );
      final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
      await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(channel);
    }
    

内容的提问来源于stack exchange,提问作者Matteo Preda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:18:15