识别控制器


识别控制器

Amazon Fire TV 平台允许用户同时连接多达七个蓝牙控制器。如果您的应用或游戏支持来自多个用户或玩家的输入,则您需要能够确定连接的控制器,识别这些控制器的功能,并区分来自不同控制器的用户输入。

Fire TV 平台使用 InputDevice 类的标准安卓功能。InputDevice 类使您能够获取所有连接的输入设备(包括控制器)的列表,并查询输入设备的功能。

您还可以从任何键事件或动作事件获取输入设备对象,这使您能够在发生时处理来自不同控制器或不同用户的输入。

获取输入设备和设备 ID

连接到 Amazon Fire TV 的输入设备由安卓 InputDevice 类表示。在系统启动和添加新设备时,连接的输入设备将获得设备 ID。ID 列表中的输入设备可以是实际控制器(如游戏控制器),也可以表示其他形式的输入,如屏幕键盘。设备 ID 本身是任意的,不能唯一地标识特定控制器或控制器类型。

您可以获取所有可用设备 ID 的列表,以确定您的应用或游戏可用的控制器数量和类型。您还可以从特定键事件或动作事件获取设备 ID 或输入设备对象,以确定该事件所使用的控制器。

获取所有输入设备 ID

您可以使用 InputDevice.getDeviceIds() 方法获取所有可用输入设备 ID 的数组,然后使用 InputDevice.getDevice() 将这些 ID 与实际输入设备对象关联:

int[] ids = InputDevice.getDeviceIds();

for (int i=0;i < ids.length; i++) {
// 根据设备 ID 获取 InputDevice 对象
InputDevice device = InputDevice.getDevice(ids[i]);

// ...
}

请注意,您从 getDeviceIds() 方法获取的设备 ID 列表仅包含实际连接到系统的输入设备。某些蓝牙控制器在一段时间内未使用时可能会断开连接(睡眠)以节省电力,或者在控制器超出范围时也可能会断开连接。

睡眠或因其他原因不可用的控制器不会被视为已连接,且不会在设备 ID 列表中枚举。您可以通过实现 InputDeviceListener 接口来侦听控制器连接和断开事件。

从键事件或动作事件获取输入设备 ID

您可以使用 InputEvent.getDeviceId() 方法获取在事件处理程序内触发键事件或动作事件的设备的 ID:

public boolean onKeyDown(int keyCode, KeyEvent event) {
int id = event.getDeviceId();
InputDevice device = InputDevice.getDevice(id);
}

或者,只获取输入设备对象本身:

public boolean onKeyDown(int keyCode, KeyEvent event) {
InputDevice device = event.getDevice();
}

识别控制器功能

安卓输入设备 ID 是任意的,不能唯一地标识任何控制器或控制器类型。要确定输入设备的类型,请查询该设备的功能,以确定输入是来自控制器(遥控器、游戏控制器或第二屏幕应用)还是来自其他设备。

使用 InputDevice.getSources() 方法获取输入设备的功能。此方法返回指示设备功能和功能的整型位图。使用定义 InputDevice 类的常量将该位图与您的应用感兴趣的特定功能进行比较。

// 根据设备 ID 获取 InputDevice 对象
InputDevice device = InputDevice.getDevice(id);

// getSources() 为您提供一个定义设备功能的整型位图;
// 与 InputDevice 中的常量进行比较以查找控制器功能
if ((device.getSources() & InputDevice.SOURCE_CLASS_JOYSTICK != 0 {
// 这个控制器有一个操纵杆
}

您还可以使用 InputEvent.getSource() 方法直接从键事件和动作事件获取输入设备功能位图:

public boolean onGenericMotionEvent(MotionEvent event) {
// 这个事件是否来自操纵杆?
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
//... 使用操纵杆处理来自控制器的输入事件
// ...
}

此设备是游戏控制器吗?

您可以通过测试 InputDevice.SOURCE_GAMEPADInputDevice.SOURCE_JOYSTICK 常量来识别游戏控制器(包括亚马逊游戏控制器和其他游戏控制器)。请注意,此代码不区分亚马逊游戏控制器和其他制造商的蓝牙控制器。

int hasFlags = InputDevice.SOURCE_GAMEPAD | InputDevice.SOURCE_JOYSTICK;
boolean isGamepad = inputDevice.getSources() & hasFlags == hasFlags;

此设备是遥控器吗?

您可以通过 InputDevice.SOURCE_DPAD 常量识别 Amazon Fire TV 遥控器或语音遥控器。但是,由于某些键盘也可能会标识自己具有方向键,因此您还应该测试键盘类型 (InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC):

int hasFlags =  InputDevice.SOURCE_DPAD;
bool isRemote = (inputDevice.getSources() & hasFlags == hasFlags)
&& inputDevice.getKeyboardType() == InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC;

此设备是否为第二屏幕应用?

您可以使用 InputDevice.SOURCE_MOUSEInputDevice.SOURCE_TOUCHPAD 常量识别亚马逊第二屏幕应用。

int hasFlags =  InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_TOUCHPAD;
bool isRemote = inputDevice.getSources() & hasFlags == hasFlags;