i'm stuck at capturing keyboard events.
I'm working with a barcode scanner which is detected by system as traditional keyboard (it is it's only mode, my client has a lot of budget scanners which can't emulate virtual com port).
My goal is to be able to detect at which port is this scanner plugged in, capture any input from that port, and prevent it from being handled by the OS (i don't want the barcode numbers popping up on focused input).
All this must be performed by a background service, which is never an active window, AND the solution must work both on linux and on windows.
I've been able to capture the input using jnativehook, but failed to prevent it from being handled by OS.
As far as i know, it is impossible to achieve this using pure java (JVM gives access to keyboard events only when application window is focused), so how should i handle this issue? I'm okay with using jni and c++ if that's necessary, but i don't know where to start.
JNativeHook does have the ability to discard events on Windows and OSX (not Linux), however, it does not have the ability to determine which USB port the scanner is connected to. The reason it cannot consume events on Linux is because the XRecord API makes a copy of the events and doesn't sit directly on the input event loop. If the devices you are working with can utilize HID, I would take a look into some of the JNI HID library wrappers like gary-rowe/hid4java or signal11/hidapi. The assertion that "it is impossible to achieve this using pure java" is correct. The only way to do it would be though native code, and HID is the most appropriate native method to accomplish your goals. Other input methods like input hooking (used by JNativeHook) will not be able to provide you with the source USB port, nor can they consume events on some platforms (Linux). There is another option out there like melloware/jintellitype that use a different mechanism for capturing input. I don't think it can grab input based on the port, however, the non-portable Linux equivalent of this library uses the XGrab API which will only consume events, but again, I don't know if it will be practical for your input source as I think it can only bind one key per call and that key must use a modifier.
Hope this helps you move forward with your project.
Related
Is there a way how to block keyboard input in java. I would like to catch the input in the java code, but stop it from being send to OS.
Example: i have notepad opened and i can write just fine, but when i press a combination of keys java app catches that input, and now i should not be able to write with my keyboard. Is this kind of behaviour possible?
I know how to capture key presses but the keyboard blocking part is a mystery to me.
I tried googling it but i did not find any solution.
You have to understand: java applications run with the JVM. A JVM isn't the operating system.
Therefore your ways to access resources belonging to the operating system are very limited.
In other words: there is no generic, cross plattform way of having a Java application being able to "intersect" arbitrary console user input for arbitrary other applications.
Imagine you are a person sitting in a bus - just a guy like everybody else. You have no authority to turn to fellow passengers and ask them for their passport or such things. You are just one guy in the bus, like everybody else. Same here: a Java application is lacking the means to control other processes.
As you are specifically asking about the Windows platform: there might be some options using JNI and specific native calls. See here for example.
So, to be precise: it is not possible in general, but depending on your operating system there might be ways, for example using JNI.
Yes, you can do this - I used this library:
https://github.com/tulskiy/jkeymaster
to successfully to register a "global" keyboard shortcut to open a window in my program that was running in the task tray.
You can't "stop" it from being sent to the OS, but you can register a keyboard shortcut, open your window, and give it focus, so that all other keystrokes go into that text box.
I'm looking to write a relatively simple key macro for my own edification and also for my own use.
I intend for it to be able to run in the background when I run other programs, and at the press of a button will enter certain text into the active window. To be more specific, I want to go in a video game and use it to automatically send messages instead of having to type them.
I Googled around a bit, but apparently I'm not using the right keywords because I'm not really sure where to start. The closest I came was finding the Keystroke class, but that appears to be used for receiving keystrokes, not sending them.
I would appreciate and info regarding, or directing me to a resource for, these issues (how to send keystrokes to windows and anything about targeting which window etc).
To send key strokes you can use java.awt.Robot
To Choose which window to activate you can look around for ws script (windows script) or old VB6 code and use it to make VB script (simple text file of extn .vbs)
Or you can junk all that and use http://www.autohotkey.com/ which has window activation, sending keys, doing things on press of certain keys (like Windows Key + B) or macros.
To get a window to activate I had made an exe long back, but no longer use it, can get it from http://sourceforge.net/projects/win-utils/files/Window-Position/rel%2001/ (but only get this if the others do not work as need to seperately get COMCTL32.ocx and install that
If you do not want to use autohotkey you can use Jini to call platform specific functions, with a wrapper to call correst OSes functions. Never done it my self, when i had to use it i would make a process to call a exe that made the window come the front.
Is there a way to detect key input when the window is not active? That is, another application is running but the program is triggered when say the F9 key is pressed or something along those lines.
Is that possible or is java not compatible for such functions? From what I found java can't get input unless it's the active window.
Note:
I typically use keylistener, which seems to stop working (with good reason) when I am not actively using the program.
It sounds like you want low level keyboard hooks.
Get global keyboard input with Java
It's not directly possible in Java (i.e. with pure Java code), but you could reference other libraries (or make your own) to acheieve this. A quick google search gives a lot of references and free/open libraries that can give you keyboard and mouse hooks (both very handy).
Hope that helps.
I'm looking for a language or library to allow me to simulate key strokes at the maximum level possible, without physically pressing the key.
(My specific measure of the level of the keystroke is whether or not it will produce the same output as a physical Key Press when my computer is already running key listeners (such as MouseKeys and StickyKeys)).
I've tried many methods of keystroke emulation;
The java AWT library, Java win32api, python win32com sendKeys, python ctypes Key press, and many more libraries for python and Java, but none of them simulate the key stroke at a close enough level to actual hardware.
(When Windows MouseKeys is active, sending a key stroke of a colon, semi colon or numpad ADD key just produces those characters, where as a physical press performs the MouseKeys click)
I believe such methods must involve sending the strokes straight to an application, rather than passing them just to the OS.
I'm coming to the idea that no library for these high (above OS code) level languages will produce anything adequate. I fear I might have to stoop to some kind of BIOS programming.
Does anybody have any useful information on the matter whatsoever?
How would I go about emulating key presses in lower level languages?
Should I be looking for a my-hardware-specific solution (some kind of Fujitsu hardware API)?
I almost feel it would be easier to program a robot to simply sit by the hardware and press the keys.
Thanks!
Second solution, super convoluted, a ton of virtualization, diabolical, totally untested, but theoretically should work, unless the datasnip program doesn't actually write to the keyboard buffer, but instead simulates keystrokes like you've been trying to. That would suck, and I would find the description of their product to be highly misleading.
You'll need:
http://www.priority1design.com.au/datasnip.html
http://sourceforge.net/projects/com0com/
And some knowledge of writing to com ports... which, looks like there's a good python module here: http://pyserial.sourceforge.net/
First, write a small program that will send characters, hexcode, etc. as necessary to the COM port of your choosing. Second, create a virtual COM port pair using com0com. At this point, connect your program to one of the COM ports created, and datasnip to the other, making sure that both sides of the communication are using identical baud rates, parity and stop bits, and data length parameters.
At this point you should have a keyboard that is identical to a hardware one, as far as the OS can tell.
I used this solution http://oblita.com/interception.html
It fully meets my needs (sending keystrokes to direct input game)
Can you use an MSDN language? They're fairly simple and well documented (google searches are better than the msdn website, for navigation, usually)
I found this bit, and I couldn't tell you if it simulates keystrokes at a level close enough to the hardware, but it does appear to be able to generate keystroke events that other programs can recognize, which is what your ultimate goal is.
http://msdn.microsoft.com/en-us/library/ms171548.aspx
The 'Send' and 'SendWait' Methods seem to be the key ones.
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.sendwait.aspx
Godspeed.
I'm not on a Windows box to test it against MouseKeys, so no guarantees that it will work, but have you tried AutoHotkey?
I'm writing an application that monitors the person’s mouse and keyboard. If they have not used the keyboard or mouse for 1 minute, it will pop up a message that says “You have not used the mouse or keyboard for 1 minute” along with an OK button.
How do I do this in Java?
You need a bit of C/C++ code and call SetWindowsHookEx This function allows you to hook into Windows events and receive a copy.
This question contains code to get you started: JNA Keyboard Hook in Windows
If you want to do this for only your application, then its very simple. You can simply add listerns i.e Toolkit.getDefaultToolkit.addAwtEventListener(..).
But for the system as a whole, I am afraid, it cannot be done in java, you may use JNI though.
If you only want to monitor activity in Java application windows, it's trivial – all you have to do is register to the appropriate event.
But to monitor all mouse and keyboard activity in the OS you will have to hook to the API which is platform dependent and will require using the JNI