Фильтровать реальные устройства ввода
Я пытаюсь получить список подключенных геймпадов следующим образом:
InputDevice.getDeviceIds()
.map { InputDevice.getDevice(it) }
.filter { it.sources and InputDeviceCompat.SOURCE_GAMEPAD == InputDeviceCompat.SOURCE_GAMEPAD }
.forEach {
Log.i("gamepads", "$it")
}
В общем, он должен возвращать только геймпады, но для моего телевизора Nexus этот блок находит еще 2 устройства одного типа:
Input Device 4: virtual-search
Descriptor: 38c59f5a8771de8bd485da05030eb001094d7936
Generation: 10
Location: built-in
Keyboard Type: non-alphabetic
Has Vibrator: false
Has mic: false
Sources: 0x701 ( keyboard dpad gamepad )
Интересный факт: хотя эти устройства явно виртуальные, звоните InputDevice.isVirtual()
возвращает ложь для обоих.
Таким образом, самым простым решением будет фильтрация устройств на основе mLocation
поле InputDevice
, К счастью, InputDevice
есть публичный способ проверить это. К сожалению, этот метод InputDevice.isExternal()
помечен как скрытый, поэтому недоступен.
Есть ли другой способ отфильтровать эти виртуальные устройства без доступа к скрытым методам / полям через отражение?
1 ответ
Похоже, что возможным решением является фильтрация устройств на основе vendorId
, Для этих virtual-search
те, InputDevice.getVendorId()
возвращается 0
в то время как это ненулевое для реальных внешних устройств.
Конечно, я запрещаю использовать некоторые неименные устройства с пустым идентификатором поставщика, но это все же лучше, чем доступ к скрытым методам, которые фактически не гарантируют работу.