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

在Java中检测显示器背光开启事件(Windows 8.1环境)

在Java中检测Windows 8.1显示器背光状态的方法

Java标准库本身没有提供直接检测显示器背光状态的API,不过我们可以通过调用Windows原生系统API来实现这个需求,最便捷的方式是使用JNA(Java Native Access)库——它能让我们不用编写C/C++代码就能直接调用Windows的DLL函数。

核心思路

Windows系统会在电源状态(包括显示器背光)变化时广播WM_POWERBROADCAST消息,我们可以监听这个消息来捕获显示器从关闭到开启的事件;另外也可以通过轮询的方式主动查询显示器的电源状态。下面分别介绍这两种方案:

方案一:监听系统电源广播消息(推荐,高效)

这种方式能实时捕获显示器状态变化,不需要轮询,步骤如下:

  1. 引入JNA依赖
    如果用Maven管理项目,添加以下依赖到pom.xml:
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.13.0</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>5.13.0</version>
</dependency>
  1. 编写代码监听电源消息
    我们需要创建一个隐藏的Windows窗口来接收系统广播的电源消息,然后在消息回调中处理显示器开启事件:
import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;

public class MonitorPowerListener {
    // 显示器电源状态对应的系统GUID
    private static final String GUID_MONITOR_POWER_ON = "02731015-4510-4526-99E6-E5A17EBD1AEA";

    public static void main(String[] args) {
        // 注册窗口类,用于接收系统消息
        WinUser.WNDCLASSEX wClass = new WinUser.WNDCLASSEX();
        wClass.lpfnWndProc = new WinUser.WindowProc() {
            @Override
            public WinDef.LRESULT callback(WinDef.HWND hwnd, int uMsg, WinDef.WPARAM wParam, WinDef.LPARAM lParam) {
                // 处理电源广播消息
                if (uMsg == WinUser.WM_POWERBROADCAST) {
                    if (wParam.intValue() == WinUser.PBT_POWERSETTINGCHANGE) {
                        WinUser.POWERBROADCAST_SETTING setting = new WinUser.POWERBROADCAST_SETTING(lParam);
                        // 判断是否是显示器电源状态变化
                        if (GUID_MONITOR_POWER_ON.equals(setting.PowerSetting.toString())) {
                            // Data[0]的值:0=关闭,1=开启,2=待机
                            int powerState = setting.Data[0];
                            if (powerState == 1) {
                                // 显示器已开启,执行自定义函数
                                onMonitorTurnedOn();
                            }
                        }
                    }
                    return new WinDef.LRESULT(1); // 告知系统已处理该消息
                }
                return User32.INSTANCE.DefWindowProc(hwnd, uMsg, wParam, lParam);
            }
        };
        wClass.lpszClassName = Native.malloc(100);
        Native.setWideString(wClass.lpszClassName, "MonitorPowerListenerClass");
        User32.INSTANCE.RegisterClassEx(wClass);
        WinDef.HWND hwnd = User32.INSTANCE.CreateWindowEx(0, wClass.lpszClassName, "MonitorPowerListener", 0, 0, 0, 0, 0, null, null, null, null);

        // 注册监听显示器电源设置变化
        WinDef.GUID guid = new WinDef.GUID(GUID_MONITOR_POWER_ON);
        User32.INSTANCE.RegisterPowerSettingNotification(hwnd, guid, 0);

        // 启动消息循环,保持程序运行以接收消息
        WinUser.MSG msg = new WinUser.MSG();
        while (User32.INSTANCE.GetMessage(msg, null, 0, 0) != 0) {
            User32.INSTANCE.TranslateMessage(msg);
            User32.INSTANCE.DispatchMessage(msg);
        }

        // 清理资源
        User32.INSTANCE.UnregisterClass(wClass.lpszClassName, null);
        Native.free(wClass.lpszClassName);
    }

    // 自定义的显示器开启时执行的函数
    private static void onMonitorTurnedOn() {
        System.out.println("显示器已开启,执行指定操作...");
        // 这里替换成你的业务逻辑代码
    }
}

方案二:轮询查询显示器状态(简单,适合小型程序)

如果不想处理复杂的消息监听,可以每隔一段时间主动查询显示器的电源状态:

import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.ptr.IntByReference;

public class MonitorPowerPoller {
    // 显示器电源状态常量:1=开启,3=关闭
    private static final int MONITOR_ON = 1;
    private static final int MONITOR_OFF = 3;

    public static void main(String[] args) throws InterruptedException {
        boolean wasOff = false;
        // 每隔1秒查询一次状态(可根据需求调整间隔)
        while (true) {
            WinDef.HWND desktopHwnd = User32.INSTANCE.GetDesktopWindow();
            IntByReference powerState = new IntByReference();
            if (User32.INSTANCE.GetMonitorPowerState(desktopHwnd, powerState)) {
                int currentState = powerState.getValue();
                // 判断是否是从关闭变为开启
                if (wasOff && currentState == MONITOR_ON) {
                    onMonitorTurnedOn();
                    wasOff = false;
                } else if (currentState == MONITOR_OFF) {
                    wasOff = true;
                }
            }
            Thread.sleep(1000);
        }
    }

    private static void onMonitorTurnedOn() {
        System.out.println("显示器已开启,执行指定操作...");
        // 这里替换成你的业务逻辑代码
    }
}

注意事项

  • 以上代码仅适用于Windows系统,在其他操作系统上无法运行;
  • 确保JNA依赖版本正确,避免出现兼容性问题;
  • 监听消息的方式需要保持消息循环运行,否则无法接收系统广播;
  • 轮询间隔越小越灵敏,但会消耗更多CPU资源,建议根据实际需求调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:57:57