【问题标题】:Java: Checking if PC is idleJava:检查PC是否空闲
【发布时间】:2011-02-16 04:22:17
【问题描述】:

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

我能想到的唯一方法是连接鼠标/键盘并设置一个计时器。

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

【问题讨论】:

  • 没有便携的方法可以做到这一点。你的目标是什么系统?你对空闲的定义是什么?
  • 也许您在这个相关问题中找到了解决方案:stackoverflow.com/questions/614227/…

标签: java keyboard desktop-application idle-processing


【解决方案1】:

Java 无法在应用程序之外的系统级别与键盘或鼠标进行交互。

That being said here are several ways to do it in Windows。最简单的大概是设置JNI和poll

GetLastInputInfo

用于键盘和鼠标活动。

【讨论】:

    【解决方案2】:

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

    你可以使用 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+")");
            }
        }
    }
    

    用您的逻辑替换打印语句,例如如果在某个时间间隔内说 1 分钟鼠标的过去位置与新位置相同(您可以只比较 x 坐标),这意味着系统处于空闲状态,并且您可以根据需要继续执行您的操作(希望这是您想要实施的合法活动:-)

    请务必在新线程中实现,否则您的主程序将挂起以检查空闲状态。

    【讨论】:

      【解决方案3】:

      您可以借助 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();
          }
      }
      

      【讨论】:

      • 但是话又说回来,为什么不只使用鼠标监视器,然后把剩下的扔掉:)
      • 我可以想象你在写学校或工作论文时鼠标闲置了很长时间;)
      【解决方案4】:

      独立于平台的 JRE 中没有任何内容可以回答这个问题。您可能可以通过测量时钟时间进行计算来猜测,但这并不可靠。在特定平台上,可能有供应商 API 可以帮助您。

      【讨论】:

      • 我需要找到的系统空闲时间并不多。我只需要找到一个用户在过去 10 分钟内一直在使用 PC。基本上。我希望通知仅显示用户是否真的在他们的电脑上。
      • 我认为这比CPU时间占用更不可能。
      【解决方案5】:

      1) 创建一个新线程。

      2) 给它一个超超低优先级(你能做到的最低)

      3) 每隔一两秒,让线程执行一些简单的任务。如果超快,至少有 1 个 CPU 处于空闲状态。如果它运行缓慢,则至少有 1 个核心不会空闲。

      或者

      只需以低优先级运行您的程序。这将让操作系统处理让其他程序在您的程序上运行的问题。

      【讨论】:

        猜你喜欢
        • 2011-11-27
        • 1970-01-01
        • 2011-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-19
        • 2011-10-19
        相关资源
        最近更新 更多