"I'm inspired,intrigued, amazed and annoyed by how difficult, complex, rare and long time coming simple cross platform USB IO is!"
PureJavaHidApi is a crossplatform Application Programming Interface (API) for accessing USB HID devices from Java, so it is a library aimed at programmers, not end users.
PureJavaHidApi is written 100% in Java so it is easy for Java programmers to develop and debug and it requires no native libraries when deployed.
Native access to the underlaying operating system's USB device interface is provided by the wonderful JNA library which takes away all the pain of compiling and deploying native code.
In someways this is early days but the code is actual daily production use in the EazyCNC Project so there is some credibility.
The basic input/output report functionality has been tested on all supported platforms and works but some of the less common features (like feature reports) have not been tested because of lack of suitable test hardware.
At this stage some API breakage as the library matures towards simplicity maybe expected.
- Windows
- Mac OS X
- Linux
PureJavaHidApi provides the capability to enumerate (find) and open attached USB HID devices and send and receive reports i.e. chucks of bytes.
-
Ability to read and parse the report descriptors (1)
-
Persintent and sensical device path names for all platforms would be great!
(1) there is a semi-decent parser in purejavahidapi.hidparser but the ability to read raw descriptor still eludes me.
The definitive PureJavaHidApi reference is the JavaDoc .
Why would you like to use PureJavaHidApi to access HID devices?
The answer is that you usually don't!
Most HID devices (like Mouse, Keyboard etc) have specific APIs provided by the operating system and you should use those to access them.
However some device which are not really Human Interface Devices in the original intent of the USB HID standard nevertheless represent themselves as HID devices. Devices like ThinkGeek USB Rocket Launcher or Oregon Scientific WMR100 weather stations to name two.
It is specifically for accessing these types of devices that PureJavaHidApi is aimed for.
Now why do they represent represent themselves as HID devices?
For one overwhelming advantage over other class of USB devices: all major operating systems have built in HID drivers which means that no driver installation is required. Hard as it for a programmer to understand driver installation is a major hurdle and can make the difference between making the sale or not.
If you are considering developing a USB device, then incarnating it as a HID device is an option worth considering.
So what is the catch?
HID devices are limited to transferring one 64 byte packet once each 1 msec or 64000 bytes/sec each way. If you need more than that you have take an other route, I suggest you head over to libusb project .
PureJavaHidApi is by no means the only game in town, for example there is hid4java which incidentally uses JNA just like PureJavaHidApi with the difference that it builds on the C-library HIDAPI , fortunately it handles the native library distribution and deployment for you, which is great as it can be a chore.
To list all available HID devices use code like:
import purejavahidapi.*;
...
List<HidDeviceInfo> devList = PureJavaHidApi.enumerateDevices();
for (HidDeviceInfo info : devList) {
System.out.printf("VID = 0x%04X PID = 0x%04X Manufacturer = %s Product = %s Path = %s\n", //
info.getVendorId(), //
info.getProductId(), //
info.getManufacturerString(), //
info.getProductString(), //
info.getPath());
}
To find a generic USB Gamepad:
import purejavahidapi.*;
List<HidDeviceInfo> devList = PureJavaHidApi.enumerateDevices();
HidDeviceInfo devInfo = null;
for (HidDeviceInfo info : devList) {
if (info.getVendorId() == (short)0x0810 && info.getProductId() == (short)0x0005) {
devInfo = info;
break;
}
}
... and then open and attach an input report listener to it:
HidDevice dev=PureJavaHidApi.openDevice(devInfo.getPath());
dev.setInputReportListener(new InputReportListener() {
@Override
public void onInputReport(HidDevice source, byte Id, byte[] data, int len) {
System.out.printf("onInputReport: id %d len %d data ", Id, len);
for (int i = 0; i < len; i++)
System.out.printf("%02X ", data[i]);
System.out.println();
}
});
All you need to do is to place the jna.jar
ja purejahidapi.jar
in your class path and start coding.
You'll probably do this in an IDE but here is how to compile and run one of the examples from the commands line.
Check out the whole project from github and and go to the examples directory and execute this:
java -cp ../bin/purejavahidapi.jar:../lib/jna-4.0.0.jar Example1
or this if you are on Windows:
java -cp ..\bin\purejavahidapi.jar;..\lib\jna-4.0.0.jar Example1
PureJavaHidApi is BSD licensed but please note it depends on JNA which is LGPL/ASL dual licensed.
While PureJavaHidApi is totally independent developement from the great HIDAPI by SIGNAL11 a lot of the technical and intricate knowledge needed to access HID devices were cherry picked ripe from that project which I gratefully acknowledge.