Фильтровать реальные устройства ввода

Я пытаюсь получить список подключенных геймпадов следующим образом:

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в то время как это ненулевое для реальных внешних устройств.

Конечно, я запрещаю использовать некоторые неименные устройства с пустым идентификатором поставщика, но это все же лучше, чем доступ к скрытым методам, которые фактически не гарантируют работу.

Другие вопросы по тегам