有没有办法跟踪Java中给定应用程序的gui空闲和活动。我使用C#完成了这个,参考本教程: http://www.codeproject.com/Articles/13756/Detecting-Application-Idleness 我如何用Java做到这一点?
答案 0 :(得分:1)
如果您可以修改应用程序,则可以安装自己的EventQueue - http://docs.oracle.com/javase/7/docs/api/java/awt/EventQueue.html#push(java.awt.EventQueue) - 处理UI事件和绘制请求。如果无法更改应用程序,您仍然可以使用JVMTI(http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/)执行类似的操作。实施将更加困难。
答案 1 :(得分:0)
此答案适用于Windows。
以下是一些可以帮助您入门的代码段。此代码仅供参考,并不完整。完整的解决方案很漫长。
从Java跳转到本地并拨打电话 CallNtPowerInformation()请求SystemPowerInformation。 将结果传递给Java端。
ntStatus = CallNtPowerInformation(SystemPowerInformation, lpInputBuffer, nInputBufferSize, &systemPowerInformation, systemPowerInformationSize);
success = ntStatus == STATUS_SUCCESS;
if (success == FALSE) {
logErrorMessage(thisFunctionName, ntStatus);
} else {
SYSTEM_POWER_INFORMATION * p = (SYSTEM_POWER_INFORMATION *) &systemPowerInformation;
javaDefineLong(env, o, "SYSTEM_POWER_INFORMATION.CoolingMode", 0, p->CoolingMode);
javaDefineLong(env, o, "SYSTEM_POWER_INFORMATION.Idleness", 0, p->Idleness);
javaDefineLong(env, o, "SYSTEM_POWER_INFORMATION.TimeRemaining", 0, p->TimeRemaining);
javaDefineLong(env, o, "SYSTEM_POWER_INFORMATION.MaxIdlenessAllowed", 0, p->MaxIdlenessAllowed);
}
对ProcessorInformation执行相同的操作。
ntStatus = CallNtPowerInformation(ProcessorInformation, lpInputBuffer, nInputBufferSize, &processorPowerInformation, processorPowerInformationSize);
success = ntStatus == STATUS_SUCCESS;
if (success == FALSE) {
logErrorMessage(thisFunctionName, ntStatus);
} else {
int x;
for (x=0; x!=32; x++) {
PROCESSOR_POWER_INFORMATION * p = (PROCESSOR_POWER_INFORMATION *) &(processorPowerInformation[x]);
if (x != p->Number) {
break;
}
else {
javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.CurrentIdleState", x, p->CurrentIdleState);
javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.CurrentMhz", x, p->CurrentMhz);
javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.MaxIdleState", x, p->MaxIdleState);
javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.MaxMhz", x, p->MaxMhz);
javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.MhzLimit", x, p->MhzLimit);
javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.Number", x, p->Number);
}
}
}
对SystemPowerPolicyCurrent执行相同的操作。
ntStatus = CallNtPowerInformation(SystemPowerPolicyCurrent, lpInputBuffer, nInputBufferSize, &systemPowerPolicy, systemPowerPolicySize);
success = ntStatus == STATUS_SUCCESS;
if (success == FALSE) {
logErrorMessage(thisFunctionName, ntStatus);
} else {
SYSTEM_POWER_POLICY * p = (SYSTEM_POWER_POLICY *) &systemPowerPolicy;
javaDefineLong(env, o, "SYSTEM_POWER_POLICY.VideoTimeout", 0, p->VideoTimeout);
javaDefineLong(env, o, "SYSTEM_POWER_POLICY.IdleTimeout", 0, p->IdleTimeout);
javaDefineLong(env, o, "SYSTEM_POWER_POLICY.LidClose.Action", 0, p->LidClose.Action);
javaDefineLong(env, o, "SYSTEM_POWER_POLICY.IdleSensitivity", 0, p->IdleSensitivity);
javaDefineLong(env, o, "SYSTEM_POWER_POLICY.PowerButton.Action", 0, p->PowerButton.Action);
}
回到Java端。计算空闲&忙。
final long id = Java2WinPower.longs.get("SYSTEM_POWER_INFORMATION.Idleness.0").longValue();
final long is = Java2WinPower.longs.get("SYSTEM_POWER_POLICY.IdleSensitivity.0").longValue();
final float aboveT = id - is;
final float belowT = is - id;
final float hi = 100 - is;
final float lo = is;
final int a = (int) ((aboveT / hi) * 100);
final int b = (int) ((belowT / lo) * 100);
textID.setText(a == b ? "" : a > b ? ("Idle:" + a + "%") : ("Busy:" + b + "%"));
这是一个静态视图。当然,真实的观点是动态的。
有空闲和忙碌程度。例如,与闲置5%相比,30%的空闲更多闲置。 忙的也一样。忙碌的50%比忙碌的5%更忙。当您允许计算机进入睡眠或休眠状态时,您在图像中看到的SleepTimer是倒数计时器。所有数据均来自操作系统。
答案 2 :(得分:0)
如果您只想监控Java应用程序的活动,Radim的答案是正确的。如果您想按照Hovercraft Full Of Eels的建议监控整个系统的用户活动,您将需要一些本机代码。您应该能够利用JNativeHook之类的东西来完成后者。