过滤真实输入设备
Filter real input devices
我正在尝试通过以下方式获取已连接游戏手柄的列表:
InputDevice.getDeviceIds()
.map { InputDevice.getDevice(it) }
.filter { it.sources and InputDeviceCompat.SOURCE_GAMEPAD == InputDeviceCompat.SOURCE_GAMEPAD }
.forEach {
Log.i("gamepads", "$it")
}
一般来说,它应该 return 只有游戏手柄,但对于我的 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()
returns false。
因此,最简单的解决方案是根据 InputDevice
的 mLocation
字段过滤设备。幸运的是,InputDevice
有 public 方法来检查它。不幸的是,此方法 InputDevice.isExternal()
被标记为隐藏,因此不可用。
有没有其他方法可以在不通过反射访问隐藏的methods/fields的情况下过滤掉这些虚拟设备?
看起来可能的解决方案是根据 vendorId
过滤设备。对于这些 virtual-search
个 InputDevice.getVendorId()
returns 0
,而对于真实的外部设备它是非零的。
当然,我禁止自己使用一些供应商 ID 为空的无名设备,但它仍然比访问实际上无法保证有效的隐藏方法要好。
我正在尝试通过以下方式获取已连接游戏手柄的列表:
InputDevice.getDeviceIds()
.map { InputDevice.getDevice(it) }
.filter { it.sources and InputDeviceCompat.SOURCE_GAMEPAD == InputDeviceCompat.SOURCE_GAMEPAD }
.forEach {
Log.i("gamepads", "$it")
}
一般来说,它应该 return 只有游戏手柄,但对于我的 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()
returns false。
因此,最简单的解决方案是根据 InputDevice
的 mLocation
字段过滤设备。幸运的是,InputDevice
有 public 方法来检查它。不幸的是,此方法 InputDevice.isExternal()
被标记为隐藏,因此不可用。
有没有其他方法可以在不通过反射访问隐藏的methods/fields的情况下过滤掉这些虚拟设备?
看起来可能的解决方案是根据 vendorId
过滤设备。对于这些 virtual-search
个 InputDevice.getVendorId()
returns 0
,而对于真实的外部设备它是非零的。
当然,我禁止自己使用一些供应商 ID 为空的无名设备,但它仍然比访问实际上无法保证有效的隐藏方法要好。