Java:检查计算机是否处于空闲状态

6

这是一个相当棘手的问题,因为我在网上没有找到任何信息。基本上,我想知道如何在Java中检查计算机是否空闲。我希望程序仅在计算机处于活动状态时工作,但如果它处于空闲状态,则不起作用。

我唯一能想到的方法是钩取鼠标/键盘并设置一个定时器。

MSN Messenger有“离开”功能,我希望有类似的功能。


没有可移植的方法来做这件事。你的目标系统是什么?你对空闲的定义是什么? - Yann Ramin
也许你可以在这个相关的问题中找到解决方案:https://dev59.com/0EbRa4cB1Zd3GeqP3sYO - Prine
5个回答

2

你可以借助Java的机器人类来解决这个问题。

使用机器人类来截取屏幕截图,然后等待一段时间,比如60秒,再次截取屏幕截图。将两张屏幕截图进行比较,以查看是否发生了任何变化,但不要只比较每个像素。检查发生变化的像素占总像素的百分比。原因是您不希望像Windows时钟这样的小差别影响结果。如果百分比小于0.005%(或其他),则计算机可能处于空闲状态。

import java.awt.AWTException;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;

public class CheckIdle extends Thread {
    private Robot robot;
    private double threshHold = 0.05;
    private int activeTime;
    private int idleTime;
    private boolean idle;
    private Rectangle screenDimenstions;

    public CheckIdle(int activeTime, int idleTime) {
        this.activeTime = activeTime;
        this.idleTime = idleTime;

        // Get the screen dimensions
        // MultiMonitor support.
        int screenWidth = 0;
        int screenHeight = 0;

        GraphicsEnvironment graphicsEnv = GraphicsEnvironment
                .getLocalGraphicsEnvironment();
        GraphicsDevice[] graphicsDevices = graphicsEnv.getScreenDevices();

        for (GraphicsDevice screens : graphicsDevices) {
            DisplayMode mode = screens.getDisplayMode();
            screenWidth += mode.getWidth();

            if (mode.getHeight() > screenHeight) {
                screenHeight = mode.getHeight();
            }
        }

        screenDimenstions = new Rectangle(0, 0, screenWidth, screenHeight);

        // setup the robot.
        robot = null;
        try {
            robot = new Robot();
        } catch (AWTException e1) {
            e1.printStackTrace();
        }

        idle = false;
    }

    public void run() {
        while (true) {
            BufferedImage screenShot = robot
                    .createScreenCapture(screenDimenstions);

            try {
                Thread.sleep(idle ? idleTime : activeTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            BufferedImage screenShot2 = robot
                    .createScreenCapture(screenDimenstions);

            if (compareScreens(screenShot, screenShot2) < threshHold) {
                idle = true;
                System.out.println("idle");
            } else {
                idle = false;
                System.out.println("active");
            }
        }
    }

    private double compareScreens(BufferedImage screen1, BufferedImage screen2) {
        int counter = 0;
        boolean changed = false;

        // Count the amount of change.
        for (int i = 0; i < screen1.getWidth() && !changed; i++) {
            for (int j = 0; j < screen1.getHeight(); j++) {
                if (screen1.getRGB(i, j) != screen2.getRGB(i, j)) {
                    counter++;
                }
            }
        }

        return (double) counter
                / (double) (screen1.getHeight() * screen1.getWidth()) * 100;
    }

    public static void main(String[] args) {
        CheckIdle idleChecker = new CheckIdle(20000, 1000);
        idleChecker.run();
    }
}

1
但是话说回来,为什么不只使用鼠标监视器并丢弃其余部分呢 :) - Reg
2
我可以想象当你在为学校或工作写文章时,鼠标会闲置很长时间 ;) - Tim S.

2

1

虽然我不是专业人士,但我有一个想法:

你可以使用Java的鼠标信息类来检查鼠标在特定时间间隔内的位置,例如:

import java.awt.MouseInfo;

public class Mouse {
    public static void main(String[] args) throws InterruptedException{
        while(true){
            Thread.sleep(100);
            System.out.println("("+MouseInfo.getPointerInfo().getLocation().x+", "+MouseInfo.getPointerInfo().getLocation().y+")");
        }
    }
}

用你的逻辑替换print语句,例如如果在某个时间间隔内(比如1分钟),鼠标的过去位置与新位置相同(你可以只比较x坐标),那么就意味着系统处于空闲状态,你可以按照自己的意愿继续操作(希望你要实现的是合法的活动 :-))

一定要在一个新线程中实现这个功能,否则你的主程序将会挂起以检查空闲状态。


0

在平台无关的JRE中,没有任何东西可以回答这个问题。你可能可以通过测量计算的时钟时间来猜测,但这并不可靠。在特定的平台上,可能会有供应商API可以帮助你。


我需要找到的不是系统空闲时间,而是在过去的10分钟内用户是否一直在使用他们的电脑。基本上,我只想在用户实际在他们的电脑前时显示通知。 - Scott Straughan
我认为这比 CPU 时间使用还要更加不可能。 - bmargulies

-1

1) 创建一个新的线程。

2) 将其设置为超级低优先级(尽量最低)。

3) 每隔一秒或两秒,让线程执行一些简单的任务。如果速度非常快,可能有至少一个 CPU 空闲。如果速度较慢,则可能至少有一个核心不空闲。

或者

将你的程序以低优先级运行。这样操作系统会优先运行其他程序而不是你的程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接