I am creating a background Java program that will take input from a USB-enabled NFC reader and perform an API request with the data found on it (a 10 digit number). However, the readers have no software of their own, and behave like a keyboard, entering the number scanned into any selected text field.
Using JNativeHook, I was able to create a keylogger type of software that waits until a 10 digit number has been entered rapidly, then makes the API request. This approach works great, but the number is still entered in any foreground/selected text field, so I've been looking for ways to fix that.
I was wondering if there was a way to either validate all text inputs before displaying them or immediately backspace this number once it is entered.
If you would like to take a look at the entire (small) project, it is available here.
CardReaderKeylogger.java:
class CardReaderKeylogger {
static void initialize() {
//Turn off mouse logging
LogManager.getLogManager().reset();
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF);
//Key listen events
NativeKeyListener keyListener = new NativeKeyListener() {
@Override public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) { }
@Override public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) { }
String buddingID = "";
@Override public void nativeKeyPressed(NativeKeyEvent key) {
String keyPressed = NativeKeyEvent.getKeyText(key.getKeyCode());
try { //Only stores value if it's a number
Integer.parseInt(keyPressed);
//Starts a timer to reset the number if it isn't all entered in time
if (buddingID.equals("")) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override public void run() {
//System.out.println("Resetting id");
buddingID = "";
timer.cancel();
}
}, 200, 200);
}
buddingID += keyPressed;
if (buddingID.length() == 10) {
PassToggleRequest.send(buddingID);
buddingID = "";
}
} catch (NumberFormatException ex) {
buddingID = "";
}
}
};
//Enable keylogger
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
return;
}
/* Construct the object and initialize native hook. */
GlobalScreen.addNativeKeyListener(keyListener);
}
}
You will have to intercept (and stop propagation) every stroke, analyze and RESEND that to original target if it is not meant to be captured. This will obviously introduce lag to keyboard input. That's possible to do with WinAPI for sure.
According documentation this is not currently possible cross-platform, but might work on some OS.