Libusb android
A ffi wrapper around libusb
for Android.
Useful if you need more advanced USB functions than the native Java/Kotlin API in Android offers.
Credits:
Dart wrapper via libusb
https://github.com/woodemi/libusb.dart
Important
libusb has the restriction on (unrooted) Android that no USB devices can be listed and found.
Functions like libusb_get_list_devices
will not find any devices.
See libusb android readme
The devices must be listed and opened via the native Java/Kotlin API in order to obtain a native handle with which libusb can continue to work. You can use libusb_android_helper for this
Getting Started
Add a dependency to your pubspec.yaml
dependencies:
libusb_android: ^1.0.0
include the libusb_android_helper package at the top of your dart file.
import 'package:libusb_android_/libusb_android.dart';
If libusb_android_helper is not used, you have to write custom platform-specific code with Java or Kotlin:
Obtain USB permissions over the android.hardware.usb.UsbManager class
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
for (UsbDevice usbDevice : deviceList.values()) {
usbManager.requestPermission(usbDevice, mPermissionIntent);
}
Get the native FileDescriptor of the UsbDevice and transfer it to libusb_android
UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(device);
int fileDescriptor = usbDeviceConnection.getFileDescriptor();
For the use of libusb_android_helper
see the readme there.
Initialize libusb:
const String _libName = 'libusb_android';
final DynamicLibrary _dynamicLibrary = () {
if (Platform.isAndroid) {
return DynamicLibrary.open('lib$_libName.so');
}
throw UnsupportedError('Unsupported platform: ${Platform.operatingSystem}');
}();
final LibusbAndroidBindings _bindings = LibusbAndroidBindings(_dynamicLibrary);
final Pointer<Pointer<libusb_context>> _libusbContext = calloc<Pointer<libusb_context>>();
// ...
void initLibusb() {
int result = _bindings.libusb_set_option(_libusbContext.value, libusb_option.LIBUSB_OPTION_NO_DEVICE_DISCOVERY);
if (result < 0) {
throw StateError("Unable to set libusb option");
}
result =_bindings.libusb_init(_libusbContext);
if (result < 0) {
throw StateError("Unable to init libusb");
}
}
// ...
calloc.free(_libusbContext);
Get libusb_device_handle:
Pointer<Pointer<libusb_device_handle>> deviceHandle = calloc<Pointer<libusb_device_handle>>();
int result = _bindings.libusb_wrap_sys_device(_libusbContext.value, handle_from_native_android_api, deviceHandle);
if (result < 0) {
throw StateError("Unable to set device handle");
}
Pointer<libusb_device> device = _bindings.libusb_get_device(deviceHandle.value);
// ...
calloc.free(deviceHandle);
Now the libusb functions can be used normally.