When I was
working on a project to shut down the systems that were left turn on
after use by students in a computer lab, then I searched a lot of
Java code to detect mouse and keyboard activity by users. Since you
all know that you can detect mouse and keyboard by Java Code but it
is limited to only frame that is focused.
Robot class lets
you know the somehow the pointer position, but it is hard to ignore
the keyboard.
After a long
search on Internet I found zOlive code (post) very useful to detect
user inactivity on windows system.
I applied whole
java source code of zOlive
in my project.
See how I applied
the zOlive
code to detect user inactivity and shutdown the system.
As said by zOlive in his post:-
Go to the directory where jna.jar was saved and create the file Win32IdleTime.java in it.
Open cmd.exe and go to the directory. Compile with
javac -classpath jna.jar Win32IdleTime.java
Run with
java -cp jna.jar;. Win32IdleTime
(replace “;” by “:” on Unix systems).
import
java.text.DateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
com.sun.jna.*
;
import
com.sun.jna.win32.*
;
/**
* 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
=
(
Kernel32
)
Native
.
loadLibrary
(
"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
=
(
User32
)
Native
.
loadLibrary
(
"user32"
,
User32
.
class
);
/**
* Contains the time of the last input.
* @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputstructures/lastinputinfo.asp
*/
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 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/getlastinputinfo.asp
* @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
};
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"
);
for
(;;)
{
int
idleSec
=
getIdleTimeMillisWin32
()
/
1000
;
State newState
=
idleSec
<
30
?
State
.
ONLINE
:
idleSec
>
5
*
60
?
State
.
AWAY
:
State
.
IDLE
;
if
(
newState
!=
state
)
{
// You can put your code here according to newstate
state
=
newState
;
System
.
out
.
println
(
dateFormat
.
format
(new
Date
())
+
" # "
+
state
);
}
try
{
Thread
.
sleep
(
1000
);
}
catch
(
Exception ex
)
{}
}
}
}
Say thanks to
zOlive to post such a nice post.
You may also find the MAC OSx version and Linux version of this code in his post.