如何使用Java检测PC已空闲30秒?
已编辑
空闲是指没有用户活动。用户在 30 秒内没有执行任何操作。我想做一个像Windows这样的应用程序,它检测到用户什么都不做并进入待机状态。
我遇到过这个使用 JNA 检测系统范围空闲时间的优秀示例。 Java Native Access (JNA) 是一个库,可提供对 Java Native Interface (JNI) 的访问,而无需您实际编写本机代码。
这是示例,非常接近您的要求。
直接从java这是不可能的。您必须找到一些本机库并为其创建一个 JNI 包装器。
不可能按照要求,但您可以使用 java.lang.management API 创建解决方法。 JNI 实现也可以在 javaworld 上找到。
这并不容易,请查看 OperatingSystemMXBean 方法 getSystemLoadAverage() 仅自 java 6 起可用,您可以跟踪它,如果一段时间内相同,则确定电脑处于空闲状态。
这假设空闲 CPU 处于空闲状态
操作系统MXBean 操作系统MxBean = ManagementFactory.getOperatingSystemMXBean();
可以使用 Jana Native Access (JNA)
旧示例代码不再适用于最新的 JNA 版本(例如 JNA 5.15.0)。请参阅下面更新的代码。
所需的依赖项:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.win32.StdCallLibrary;
/**
* Utility method to retrieve the idle time on Windows and sample code to test it.
* JNA shall be present in your classpath for this to work (and compile).
*
* @author ochafik
*/
public class Win32IdleTime {
public interface Kernel32 extends StdCallLibrary {
Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class);
/**
* Retrieves the number of milliseconds that have elapsed since the system was started.
*
* @see http://msdn2.microsoft.com/en-us/library/ms724408.aspx
* @return number of milliseconds that have elapsed since the system was started.
*/
public int GetTickCount();
};
public interface User32 extends StdCallLibrary {
User32 INSTANCE = Native.load("user32", User32.class);
/**
* Contains the time of the last input.
*
* @see https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-lastinputinfo
*/
@FieldOrder({ "cbSize", "dwTime" })
public static class LASTINPUTINFO extends Structure {
public int cbSize = 8;
/// Tick count of when the last input event was received.
public int dwTime;
}
/**
* Retrieves the time of the last input event.
*
* @see https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getlastinputinfo
* @return time of the last input event, in milliseconds
*/
public boolean GetLastInputInfo(LASTINPUTINFO result);
};
/**
* Get the amount of milliseconds that have elapsed since the last input event
* (mouse or keyboard)
*
* @return idle time in milliseconds
*/
public static int getIdleTimeMillisWin32() {
User32.LASTINPUTINFO lastInputInfo = new User32.LASTINPUTINFO();
User32.INSTANCE.GetLastInputInfo(lastInputInfo);
return Kernel32.INSTANCE.GetTickCount() - lastInputInfo.dwTime;
}
enum State {
UNKNOWN,
ONLINE,
IDLE,
AWAY
};
/**
* State:
*
* <pre>
* idle time 0-30 sec -> ONLINE
* idle time 30 sec - 5 min -> IDLE
* idle time > 5 min -> AWAY
* </pre>
*
*/
public static void main(String[] args) {
if (!System.getProperty("os.name").contains("Windows")) {
System.err.println("ERROR: Only implemented on Windows");
System.exit(1);
}
State state = State.UNKNOWN;
DateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss");
while (true) {
int idleSec = getIdleTimeMillisWin32() / 1000;
// System.out.println(idleSec);
State newState = idleSec < 30 ? State.ONLINE : idleSec > 5 * 60 ? State.AWAY : State.IDLE;
if (newState != state) {
state = newState;
System.out.println(dateFormat.format(new Date()) + " # " + state);
}
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
}
}
}