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

如何在Flutter应用中检测macOS darkwake状态并阻止同步任务?

问题描述

我用Dart/Flutter的Timer.periodic配置了服务器同步任务,发现macOS Sequoia在休眠时会偶尔进入darkwake模式,此时同步任务会被触发。由于系统常提前重回休眠或无网络,任务往往执行失败。我希望检测该darkwake状态并阻止同步任务运行,相关日志如下:

2024-11-25 21:22:38 +0100 Assertions              PID 520(powerd) Created InternalPreventSleep "Holding in darkwake for up to 20 seconds to query model for inactivity prediction" 00:00:00  id:0x0xd0000856f [System: PrevIdle SRPrevSleep kCPU]
2024-11-25 21:22:38 +0100 Assertions              PID 520(powerd) Released InternalPreventSleep "Holding in darkwake for up to 20 seconds to query model for inactivity prediction" 00:00:00  id:0x0xd0000856f [System: PrevIdle]
2024-11-25 21:22:38 +0100 Assertions              PID 630(mDNSResponder) Created MaintenanceWake "mDNSResponder:maintenance" 00:00:00  id:0x0xd00008570 [System: PrevIdle]
解决方案

方法1:通过pmset命令检测状态

macOS自带的pmset工具能查询系统电源断言,其中包含darkwake相关标识。你可以在Dart里调用系统命令获取状态:

import 'dart:io';

Future<bool> isInDarkwake() async {
  try {
    final result = await Process.run('pmset', ['-g', 'assertions']);
    if (result.exitCode == 0) {
      final output = result.stdout.toString();
      // 匹配日志里的darkwake相关特征
      return output.contains('darkwake') || 
             output.contains('SRPrevSleep') ||
             output.contains('MaintenanceWake');
    }
  } catch (e) {
    // 命令执行失败默认返回false,允许任务执行
    return false;
  }
  return false;
}

同步任务执行前调用这个方法,返回true就跳过任务:

Timer.periodic(Duration(minutes: 10), (timer) async {
  if (await isInDarkwake()) {
    print('当前处于darkwake状态,跳过同步任务');
    return;
  }
  // 执行同步逻辑
  await syncWithServer();
});

方法2:监听系统电源通知

macOS有电源状态变化的通知机制,你可以通过Flutter的原生通道来监听,提前获知darkwake状态:

  1. macOS原生端(Swift):注册监听,检测到darkwake时通知Dart层
import Cocoa
import FlutterMacOS

class MainFlutterWindow: NSWindow {
    override func awakeFromNib() {
        let flutterViewController = FlutterViewController.init()
        let windowFrame = self.frame
        self.contentViewController = flutterViewController
        self.setFrame(windowFrame, display: true)
        
        let channel = FlutterMethodChannel(name: "com.example.power", binaryMessenger: flutterViewController.engine.binaryMessenger)
        
        // 监听电源状态通知
        NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "IOPMPowerSourceNotification"), object: nil, queue: nil) { notification in
            if let info = notification.userInfo, let isDarkwake = info["DarkWake"] as? Bool {
                channel.invokeMethod("onDarkwakeStateChanged", arguments: isDarkwake)
            }
        }
        
        super.awakeFromNib()
    }
}
  1. Dart层:接收回调并维护状态
import 'package:flutter/services.dart';

bool _isInDarkwake = false;

void setupPowerListener() {
  const channel = MethodChannel('com.example.power');
  channel.setMethodCallHandler((call) async {
    if (call.method == 'onDarkwakeStateChanged') {
      _isInDarkwake = call.arguments as bool;
    }
  });
}

// 任务中使用状态判断
Timer.periodic(Duration(minutes: 10), (timer) async {
  if (_isInDarkwake) {
    print('当前处于darkwake状态,跳过同步任务');
    return;
  }
  await syncWithServer();
});

方法3:结合网络可达性检测

除了检测darkwake,还可以额外判断网络是否可用,双重避免任务失败:

import 'package:connectivity_plus/connectivity_plus.dart';

Future<bool> canPerformSync() async {
  final isDarkwake = await isInDarkwake();
  if (isDarkwake) return false;
  
  final connectivityResult = await Connectivity().checkConnectivity();
  return connectivityResult != ConnectivityResult.none;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:03:16