android_hid_gamepad 0.0.1
android_hid_gamepad: ^0.0.1 copied to clipboard
A Flutter plugin for Android HID Gamepad using Bluetooth
android_hid_gamepad #
A new Flutter plugin that converts your Android Phone to a Bluetooth HID Gamepad for your PC.
It uses Android's native Bluetooth HID profile, this package communicates directly with the operating system on the target machine. The computer natively recognizes your phone as a standard game controller without the need of any software on your PC.
Features #
- Registers the Android device as an official Bluetooth HID Gamepad.
- Transmits 4 Buttons (ABXY) and an analog joystick axis simultaneously. (Can be extended easily to more buttons and inputs)
- Supports connection to all windows PCs with bluetooth.
- Real-time & fast input via native Bluetooth profiles.
Setup #
Flutter App #
Create a new flutter app and add the package to the project using
flutter create project_name
cd project_name
flutter pub add android_hid_gamepad
Permissions & MinSdk #
Add the following permissions to your application's android/src/main/AndroidManifest.xml file to allow the native Bluetooth manager to pair and transfer reports:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
Currently the package requires the minimum Android Sdk to be version 28 so in project_name/android/app/build.gradle change the minSdk to 28 or greater.
Usage #
- Initialization and Connection
// import the package
import 'package:android_hid_gamepad/android_hid_gamepad.dart';
...
// Call the constructor for the plugin
final hidPlugin = AndroidHidGamepad();
// Step 1: Initialize the Gamepad profile to begin broadcasting to nearby PCs
await hidPlugin.initialiseGamePad();
// Step 2: Request to pair via bluetooth from your PC
// Step 3: Check if a PC has established an incoming connection to the phone, gives [Name, MACAddress] of the connected PC
List<String>? pcInfo = await hidPlugin.getConnectedDevice();
if (pcInfo != null) {
print("Connected to: ${pcInfo[0]} (${pcInfo[1]})");
}
// Step 3: (Optional) Connect to a specific MAC using either Hardcoded or Bluetooth Scan MAC Address
String MAC = "00:11:22:33:44:55"; // Or get this from Bluetooth scan module
await hidPlugin.connectToPC(MAC);
// Step 4: Disconnect at wish
await hidPlugin.disconnect();
- Sending Input Data
The current HID_Descriptor consists of 4 input buttons (ABXY) and one JoyStick with two Axes.
private static final byte[] HID_DESCRIPTOR = {
(byte) 0x05, (byte) 0x01, // Usage Page (Generic Desktop)
(byte) 0x09, (byte) 0x05, // Usage (Gamepad)
(byte) 0xA1, (byte) 0x01, // Collection (Application)
(byte) 0x85, (byte) 0x01, // Report ID (1)
(byte) 0x05, (byte) 0x09, // Usage Page (Buttons)
(byte) 0x19, (byte) 0x01, // Usage Minimum (1)
(byte) 0x29, (byte) 0x04, // Usage Maximum (4) ← 4 buttons
(byte) 0x15, (byte) 0x00, // Logical Minimum (0)
(byte) 0x25, (byte) 0x01, // Logical Maximum (1)
(byte) 0x75, (byte) 0x01, // Report Size (1 bit each)
(byte) 0x95, (byte) 0x04, // Report Count (4)
(byte) 0x81, (byte) 0x02, // Input (Data, Variable, Absolute)
(byte) 0x75, (byte) 0x04, // Report Size (4 bit padding)
(byte) 0x95, (byte) 0x01, // Report Count (1)
(byte) 0x81, (byte) 0x03, // Input (Constant) ← pad to full byte
(byte) 0x05, (byte) 0x01, // Usage Page (Generic Desktop)
(byte) 0x09, (byte) 0x30, // Usage X-axis
(byte) 0x09, (byte) 0x31, // Usage Y-axis
(byte) 0x15, (byte) 0x81, // Logical Min
(byte) 0x25, (byte) 0x7f, // Logical Max
(byte) 0x75, (byte) 0x08, // Report Size (8 bit)
(byte) 0x95, (byte) 0x02, // Report Count (2) ← 2 joysticks with 1 byte data each
(byte) 0x81, (byte) 0x02, // Input (Data, Variable, Absolute)
(byte) 0xC0 // End Collection
};
This is the simplest HID_Descriptor and can be changed in AndroidHidGamepadPlugin.java to meet any needs.
Now, for this descripter, we need to send a byte array of length 3 to the connected PC, [Buttons, JoystickX, JoystickY]
- Buttons(Byte 0) is for the 4 Buttons:
(A = 1, B = 2, X = 4, Y = 8)and consists of 4 important bits and 4 padding bits. Ex.Buttons=10represents the state when B and Y are pressed and A and X are not pressed. - Joystick(Byte 1 & 2) is for the joystick input values from -127 to 127, 8-bit signed integers.
// Example: Pressing B and Y buttons and moving joystick
List<int> inputData = [10, 100, 100];
// Sending the inputData to the package, after connecting
await hidPlugin.sendInputData(inputData);
Example Application #
A complete application has been implemented in the example/ directory of the package featuring a simple layout of 4 buttons and a joystick.
Feel free to fork/clone the repository and try to modify the plugin according to your needs!
Further Improvements #
This is a boilerplate plugin and has lots of potential to improve such as:
- Making the HID_Descripter bytearray modifiable and hence adding variable inputs according to need
- Adding a better functionality towards bluetooth connections such as scanning nearby devices
- Having a device connection history
- Fixing the error catching methods and logic flow
Made by SokaNanD with Fun.