Java: Checking if PC is idle
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.
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.
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.
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();
}
}
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.
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.
精彩评论