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

如何在Java中检测macOS笔记本电脑的睡眠状态

在Java中检测macOS睡眠与唤醒状态

使用Java 9+的SystemSleepListener(推荐方案)

从Java 9开始,java.awt.Desktop提供了SystemSleepListener接口,可直接监听macOS的睡眠和唤醒事件,这是最优雅且可靠的方式。以下是结合你的ping线程场景的完整实现示例:

import java.awt.Desktop;
import java.awt.SystemSleepEvent;
import java.awt.SystemSleepListener;

public class SleepAwarePingClient {
    private Thread pingServerThread;

    public static void main(String[] args) {
        SleepAwarePingClient client = new SleepAwarePingClient();
        client.registerSleepListener();
        client.launchPingThread();
    }

    private void registerSleepListener() {
        Desktop desktop = Desktop.getDesktop();
        desktop.addSystemSleepListener(new SystemSleepListener() {
            @Override
            public void systemAboutToSleep(SystemSleepEvent event) {
                // 系统即将进入睡眠,中断ping线程
                if (pingServerThread != null && pingServerThread.isAlive()) {
                    pingServerThread.interrupt();
                    System.out.println("[Sleep Trigger] 中断ping线程");
                }
            }

            @Override
            public void systemAwoke(SystemSleepEvent event) {
                // 系统唤醒,重启ping线程
                launchPingThread();
                System.out.println("[Wake Trigger] 重启ping线程");
            }
        });
    }

    private void launchPingThread() {
        pingServerThread = new Thread(() -> {
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    // 替换为你的实际ping服务器逻辑
                    sendPingRequest();
                    // 模拟ping间隔(5秒)
                    Thread.sleep(5000);
                }
            } catch (InterruptedException e) {
                // 捕获中断信号,优雅退出线程
                System.out.println("[Ping Thread] 收到中断信号,停止运行");
                Thread.currentThread().interrupt(); // 保留中断状态供上层判断
            }
        }, "pingServer");
        pingServerThread.start();
    }

    private void sendPingRequest() {
        // 你的ping请求实现
        System.out.println("[Ping Thread] 发送ping请求到服务器");
    }
}

关键说明:

  • 事件触发时机:systemAboutToSleep在系统正式睡眠前触发,此时可安全完成线程中断等清理操作;systemAwoke在系统完全唤醒后触发,可重启业务线程。
  • 线程中断处理:ping线程通过Thread.currentThread().isInterrupted()判断是否退出循环,捕获InterruptedException后重置中断状态,避免后续逻辑忽略中断信号。
  • 版本与兼容性:该API仅支持Java 9及以上版本,macOS全版本兼容,部分新系统可能需要授予Java程序“辅助功能”权限以确保事件监听正常。

Java 8及以下版本的替代方案

如果项目基于Java 8,无法使用SystemSleepListener,可通过调用macOS原生命令pmset轮询系统状态:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class SleepPollingClient {
    private Thread pingServerThread;

    public static void main(String[] args) {
        SleepPollingClient client = new SleepPollingClient();
        client.startSleepPoller();
        client.launchPingThread();
    }

    private void startSleepPoller() {
        Thread pollerThread = new Thread(() -> {
            boolean wasSleeping = false;
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    Process process = Runtime.getRuntime().exec("pmset -g assertions");
                    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                    String line;
                    boolean isSleeping = false;

                    while ((line = reader.readLine()) != null) {
                        // 解析pmset输出,判断系统是否允许睡眠
                        if (line.contains("PreventUserIdleSystemSleep") && line.trim().endsWith("0")) {
                            isSleeping = true;
                            break;
                        }
                    }

                    reader.close();
                    process.waitFor();

                    // 状态变化时执行对应操作
                    if (isSleeping && !wasSleeping) {
                        if (pingServerThread != null && pingServerThread.isAlive()) {
                            pingServerThread.interrupt();
                            System.out.println("[Poller] 检测到睡眠状态,中断ping线程");
                        }
                    } else if (!isSleeping && wasSleeping) {
                        launchPingThread();
                        System.out.println("[Poller] 检测到唤醒状态,重启ping线程");
                    }

                    wasSleeping = isSleeping;
                    Thread.sleep(10000); // 每10秒轮询一次
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        pollerThread.start();
    }

    private void launchPingThread() {
        pingServerThread = new Thread(() -> {
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    sendPingRequest();
                    Thread.sleep(5000);
                }
            } catch (InterruptedException e) {
                System.out.println("[Ping Thread] 收到中断信号,停止运行");
                Thread.currentThread().interrupt();
            }
        }, "pingServer");
        pingServerThread.start();
    }

    private void sendPingRequest() {
        System.out.println("[Ping Thread] 发送ping请求到服务器");
    }
}

注意事项:

  • 轮询方式存在延迟,无法像监听器那样实时响应睡眠事件。
  • pmset的输出格式可能随macOS版本变化,需根据实际系统调整解析逻辑。
  • 需确保Java程序有权限执行终端命令,部分系统可能需要授予“完全磁盘访问”权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:30:37