Не удается отправить события клавиатуры на устройство, подключенное по Bluetooth HID

#android #android-bluetooth #hid

Вопрос:

Я могу успешно подключиться к устройству Bluetooth HID и управлять кнопкой «Домой» сопряженного устройства и кнопками навигации. Но не удается правильно отправить события клавиш клавиатуры на скрытое устройство. Когда я что-то печатаю на главном устройстве, скрытое устройство реагирует случайными действиями.

У меня есть следующий код для соединения с массивом дескрипторов,

 override fun onServiceConnected(profile: Int, proxy: BluetoothProfile?) {
            if (profile == BluetoothProfile.HID_DEVICE) {
                mBtHidDevice = proxy as BluetoothHidDevice

                val sdp = BluetoothHidDeviceAppSdpSettings(
                    "HidControl",
                    "Android HID Joystick",
                    "Android",
                    0xC0.toByte(),
                    descriptor
                )
           }
       }
 

Массив дескрипторов выглядит следующим образом,

 private val descriptor = byteArrayOf( // HID descriptor
    0x09,  // bLength
    0x21,  // bDescriptorType - HID
    0x11, 0x01,  // bcdHID (little endian - 1.11)
    0x00,  // bCountryCode
    0x01,  // bNumDescriptors (min 1)
    0x22,  // bDescriptorType - Report
    0x30, 0x00,  // wDescriptorLength (48)
    // Report descriptor
    0x05, 0x01,  // USAGE_PAGE (Generic Desktop)
    0x09, 0x06,  // USAGE (Key board)
    0xa1.toByte(), 0x01,  // COLLECTION (Application)
    0xa1.toByte(), 0x00,  //   COLLECTION (Physical)
    0x05, 0x09,  //     USAGE_PAGE (Button)
    0x19, 0x01,  //     USAGE_MINIMUM (Button 1)
    0x29, 0x04,  //     USAGE_MAXIMUM (Button 4)
    0x15, 0x00,  //     LOGICAL_MINIMUM (0)
    0x25, 0x01,  //     LOGICAL_MAXIMUM (1)
    0x75, 0x01,  //     REPORT_SIZE (1)
    0x95.toByte(), 0x04,  //     REPORT_COUNT (4)
    0x81.toByte(), 0x02,  //     INPUT (Data,Var,Abs)
    0x75, 0x04,  //     REPORT_SIZE (4)
    0x95.toByte(), 0x01,  //     REPORT_COUNT (1)
    0x81.toByte(), 0x03,  //     INPUT (Cnst,Var,Abs)
    0x05, 0x01,  //     USAGE_PAGE (Generic Desktop)
    0x09, 0x30,  //     USAGE (X)
    0x09, 0x31,  //     USAGE (Y)
    0x15, 0x81.toByte(),  //     LOGICAL_MINIMUM (-127)
    0x25, 0x7f,  //     LOGICAL_MAXIMUM (127)
    0x75, 0x08,  //     REPORT_SIZE (8)
    0x95.toByte(), 0x02,  //     REPORT_COUNT (2)
    0x81.toByte(), 0x02,  //     INPUT (Data,Var,Abs)
    0xc0.toByte(),  //   END_COLLECTION
    0xc0.toByte() // END_COLLECTION
)
 

Код для отправки событий клавиатуры на целевое устройство приведен ниже

 override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
    Log.d("Key Codes ", "$keyCode   event: $event")
    for (btDev in mBtHidDevice!!.connectedDevices) {

        mBtHidDevice!!.sendReport(
            btDev, 0, byteArrayOf(event!!.keyCode.toByte())
        )
        mBtHidDevice!!.sendReport(
            btDev, 0, byteArrayOf(
                0
            )
        )
    }
    return super.onKeyUp(keyCode, event)

}
 

Пожалуйста, подскажите, не упускаю ли я здесь чего-нибудь. Спасибо за помощь!

Комментарии:

1. Я не эксперт по Kotlin или bluetooth, поэтому я не могу дать реальный ответ, но я думаю, что несколько вещей требуют внимания: 1. Подкласс устройства BluetoothHidDeviceAppSdpSettings должен быть 0x00 (не 0xc0.toByte()), 2. Я бы удалил все экземпляры . toByte (), потому что они ничего не делают (преобразование байта в байт), 3. Скрытый дескриптор отчета, похоже, предназначен для джойстика с 4 кнопками — поэтому я бы заменил его дескриптором отчета для клавиатуры. Пример приведен в Приложении Е к usb.org/sites/default/files/hid1_11.pdf (официальная спецификация класса USB-устройств).

Ответ №1:

Вам нужно использовать страницу использования клавиатуры.

Логический минимум и логический максимум, которые я вижу, составляют всего от 1 до 4. Вы хотели, чтобы эти обычаи остались в покое?

См. таблицу использования HID https://www.usb.org/document-library/hid-usage-tables-122

В приложении приведен пример использования клавиатуры. Вы можете сослаться на это.