Java: Checking if PC is idle
Asked Answered
S

5

6

This is a rather tricky question as I have found no information online. Basically, I wish to know how to check if a computer is idle in Java. I wish a program to only work if the computer is in active use but if it is idle then to not.

The only way i can think of doing this is hooking into the mouse/keyboard and having a timer.

MSN Messenger has that "away" feature, I wish for something similar to this.

Sheilahshekel answered 6/5, 2010 at 0:10 Comment(2)
There is no portable way of doing this. What systems are you targeting? What is your definition of idle?Gearldinegearshift
Maybe you find a solution in this related question: #614727Simonasimonds
P
2

Java has no way of interacting with the Keyboard, or Mouse at the system level outside of your application.

That being said here are several ways to do it in Windows. The easiest is probably to set up JNI and poll

GetLastInputInfo

for keyboard and mouse activity.

Parade answered 6/5, 2010 at 0:27 Comment(0)
C
2

You can solve this with the help of Java's robot class.

Use the robot class to take a screenshot, then wait for lets say 60 seconds and take another screenshot. Compare the screenshots with each other to see if any changes has happened, but don't just compare the screenshots pixel by pixel. Check for the percentage of the pixels that has changed. The reason is that you don't want small differences like Windows clock to interfere with the result. If the percentage is less that 0.005% (or whatever), then the computer is probably idling.

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();
    }
}
Chintzy answered 15/2, 2012 at 9:53 Comment(2)
But then again, why not the just only use the mouse monitor and chuck the rest :)Chintzy
I can imagine the mouse is idle for a long time when you are writing an essay for school or work ;)Caucasia
F
1

Im not a professional, but i have an idea:

you can use the java's mouse info class to check mouse position at certian intervals say like:

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+")");
        }
    }
}

replace the print statement with your logic, like if for some interval say 1 min the past position of mouse is the same as new position (you can simply compare only the x-coordinates), that means the system is idle, and you can proceed with your action as you want (Hopefully it is a legal activity that you want to implement :-)

Besure to implement this in a new thread, otherwise your main program will hang in order to check the idle state.

Foredate answered 25/12, 2010 at 0:30 Comment(0)
H
0

Nothing in the platform-independent JRE will answer this question. You might be able to guess by measuring clock time for a calculation, but it wouldn't be reliable. On specific platforms, there might be vendor APIs that might help you.

Hakim answered 6/5, 2010 at 0:24 Comment(2)
Its not so much system idle time i need to find. I just need to find it a user has been using there PC within say the last 10 mins. Basically. I want notifications to only show if the user is actually at their PC.Sheilahshekel
I think that this is even more impossible than CPU time usage.Hakim
C
-1

1) Make a new thread.

2) Give it a super super low priority (the lowest you can)

3) Every second or two, have the thread do some simple task. If super fast, at least 1 CPU is prolly idle. If it does it slow, then at least 1 core is prolly not idle.

Or

Just run your program at a low priority. That will let the OS deal with letting other programs run over your program.

Curst answered 6/5, 2010 at 2:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.