コントローラーを識別


コントローラーを識別

Amazon Fire TVプラットフォームでは、同時に最大で7つのBluetoothコントローラーに接続できます。アプリまたはゲームが複数のユーザーやプレーヤーからの入力をサポートしている場合、接続されたコントローラーを識別してそれぞれの機能を特定し、各コントローラーからのユーザー入力を区別できる必要があります。

Fire TVプラットフォームでは、Androidの標準機能であるInputDeviceクラスが使用されます。InputDeviceクラスを使用することで、接続されたすべての入力デバイス(コントローラーを含む)のリストを入手し、入力デバイスの機能を問い合わせることができます。

また、任意のキーイベントやモーションイベントから入力デバイスオブジェクトを入手できることから、異なるコントローラーやユーザーからの入力が発生した場合に、それらを処理することができます。

入力デバイスとデバイスIDの取得

Amazon Fire TVに接続された入力デバイスは、Android 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のリストには、システムに実際に接続された入力デバイスのみが含まれることに留意してください。Bluetoothコントローラーによっては、しばらくの間使用されていないと、電気を節約するために切断される(スリープ状態になる)場合があります。また接続範囲外になると、切断される場合もあります。

スリープ状態のコントローラー、またはほかの状態で利用不可能なコントローラーは、接続されているとみなされないため、デバイス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();
}

コントローラー機能の特定

Androidの入力デバイス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) {
// ...ジョイスティックでコントローラーの入力イベントを処理 }
// ...
}

デバイスがゲームコントローラーかどうかの判断

ゲームコントローラー(Amazonゲームコントローラーとほかのゲームコントローラーの両方)を特定するには、InputDevice.SOURCE_GAMEPADInputDevice.SOURCE_JOYSTICKの両方の定数をテストします。このコードでは、Amazonゲームコントローラーと他社製のBluetoothコントローラーが区別されないことに留意してください。

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

デバイスがリモコンかどうかの判断

Amazon Fire TVリモコンまたはAmazon Fire TV音声認識リモコンを特定するには、InputDevice.SOURCE_DPAD定数を使用します。ただし、一部のキーボードはD-Padを搭載していると認識される場合もあるため、キーボードの種類もテストする必要があります(以下のように、InputDevice.KEYBOARD_TYPE_NON_ALPHABETICを使用します)。

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

デバイスがセカンドスクリーンアプリかどうかの判断

Amazonセカンドスクリーンアプリを特定するには、InputDevice.SOURCE_MOUSEおよびInputDevice.SOURCE_TOUCHPADの両方の定数を使用します。

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