{"id":15177494,"url":"https://github.com/scavanger/libusb_android_helper","last_synced_at":"2026-02-27T16:38:14.381Z","repository":{"id":254775172,"uuid":"847500707","full_name":"Scavanger/libusb_android_helper","owner":"Scavanger","description":"Helper plugin for libusb_android","archived":false,"fork":false,"pushed_at":"2024-08-26T22:20:00.000Z","size":83,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-23T11:15:55.475Z","etag":null,"topics":["android","flutter","libusb"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Scavanger.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-26T01:26:24.000Z","updated_at":"2024-08-26T22:09:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"af36caac-2a45-4339-9f17-c47bd1af8aeb","html_url":"https://github.com/Scavanger/libusb_android_helper","commit_stats":{"total_commits":13,"total_committers":1,"mean_commits":13.0,"dds":0.0,"last_synced_commit":"4baeb4bd4f605ebdfbe3d18e5cccdcaa4aee97ce"},"previous_names":["scavanger/libusb_android_helper"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scavanger%2Flibusb_android_helper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scavanger%2Flibusb_android_helper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scavanger%2Flibusb_android_helper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scavanger%2Flibusb_android_helper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Scavanger","download_url":"https://codeload.github.com/Scavanger/libusb_android_helper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240304706,"owners_count":19780313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","flutter","libusb"],"created_at":"2024-09-27T14:23:17.046Z","updated_at":"2026-02-27T16:38:14.335Z","avatar_url":"https://github.com/Scavanger.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Push Validation](https://github.com/scavanger/libusb_android_helper/actions/workflows/dart.yml/badge.svg?event=push)\n# Libusb Android Helper\n\nlibusb_android has the restriction on (unrooted) Android that no USB devices can be listed and found. \nSee [libusb android readme](https://github.com/libusb/libusb/blob/master/android/README)\n\nThis helper plugin closes this gap by using the native Java API to find and open the devices and retrieve the native file descriptor to continue working with it in libusb_android.\n\nFlutter plugins cannot contain native C (ffi) and Java code at the same time, hence the split into two plugins.\n\n## Getting Started\n\nAdd a dependency to your pubspec.yaml\n\n```dart\ndependencies:\n\tlibusb_android_helper: ^1.0.0\n```\n\ninclude the libusb_android_helper package at the top of your dart file.\n\n```dart\nimport 'package:libusb_android_helper/libusb_android_helper.dart';\n```\n\n### Optional\n\nAdd\n```xml\n\u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n    \u003cuses-feature android:name=\"android.hardware.usb.host\" /\u003e\n    ...\n    \u003capplication ... \u003e\n        \u003cactivity ... \u003e\n        ...\n            \u003cintent-filter\u003e\n                \u003caction android:name=\"android.hardware.usb.action.USB_DEVICE_ATTACHED\"/\u003e\n                \u003caction android:name=\"android.hardware.usb.action.USB_DEVICE_DETACHED\"/\u003e\n            \u003c/intent-filter\u003e\n\n            \u003cmeta-data android:name=\"android.hardware.usb.action.USB_DEVICE_ATTACHED\"\n                    android:resource=\"@xml/device_filter\" /\u003e\n            \u003cmeta-data android:name=\"android.hardware.usb.action.USB_DEVICE_DETACHED\"\n                android:resource=\"@xml/device_filter\" /\u003e\n        \u003c/activity\u003e\n    \u003c/application\u003e\n\u003cmanifest\u003e\n```\nto your AndroidManifest.xml\n\nand place device_filter.xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cresources\u003e\n    \u003cusb-device vendor-id=\"[Your vid]\" product-id=\"[Your pid]\" /\u003e\n\u003c/resources\u003e\n```\nin the res/xml directory. This will notify your app when one of the specified devices\nis connected or disconnected.\n\n### Usage\n\nList all devices already connected:\n\n```dart\nFuture\u003cList\u003cUsbDevice\u003e\u003e getUsbDevices() async {\n    List\u003cUsbDevice\u003e? devices;\n    try {\n        devices = await LibusbAndroidHelper.listDevices();\n    } on PlatformException catch (e) {\n        return List\u003cUsbDevice\u003e.empty();\n    }\n    if (devices != null) {\n        return devices;\n    } else {\n        return List\u003cUsbDevice\u003e.empty();\n    }\n}\n```\n\nGet notified when a USB device is connected or disconnected:\n```dart\nLibusbAndroidHelper.usbEventStream?.listen((event) {\n    try {\n        if (event.action == UsbAction.usbDeviceAttached) {\n            _device = event.device;\n        } else if (event.action == UsbAction.usbDeviceDetached) {\n            _device = null;\n        }\n    } on PlatformException catch (e) {\n        // error\n    }\n});\n```\n\nRequest authorization to access the USB device from the user:\n```dart\nif (!(await device.hasPermission())){\n    await device.requestPermission();\n}\n```\n\nOpen the device and pass the native handle to libusb_android\n```dart\nconst String _libName = 'libusb_android';\nfinal DynamicLibrary _dynamicLibrary = () {\n  if (Platform.isAndroid) {\n    return DynamicLibrary.open('lib$_libName.so');\n  }\n  throw UnsupportedError('Unsupported platform: ${Platform.operatingSystem}');\n}();\nfinal LibusbAndroidBindings _bindings = LibusbAndroidBindings(_dynamicLibrary);\n// ...\nif (await device?.open()) {\n    int retValue = 0;\n    Pointer\u003cPointer\u003clibusb_context\u003e\u003e context = calloc\u003cPointer\u003clibusb_context\u003e\u003e();\n    Pointer\u003cPointer\u003clibusb_device_handle\u003e\u003e deviceHandle = calloc\u003cPointer\u003clibusb_device_handle\u003e\u003e();\n    \n    retValue = _bindings.libusb_set_option(context.value, libusb_option.LIBUSB_OPTION_NO_DEVICE_DISCOVERY);\n    if (retValue \u003c 0) {\n        return;\n    }\n\n    retValue =_bindings.libusb_init(context);\n    if (retValue \u003c 0) {\n        return;\n    }\n\n    retValue = _bindings.libusb_wrap_sys_device(context.value, device!.handle, deviceHandle);\n    if (retValue \u003c 0) {\n        return;\n    }\n\n    Pointer\u003clibusb_device\u003e device = _bindings.libusb_get_device(deviceHandle.value);\n\n    // Work with device\n}\n// ...\n// Don't forget\ncalloc.free(context);\ncalloc.free(dev_handle);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscavanger%2Flibusb_android_helper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscavanger%2Flibusb_android_helper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscavanger%2Flibusb_android_helper/lists"}