テレビデバイスでは、アプリを操作するためのセカンダリ ハードウェア デバイス(基本リモコン、ポインタ リモコン、ゲーム コントローラ)が必要です。一貫したユーザー エクスペリエンスを提供するには、アプリで十字キー(D-pad)による入力をサポートし、コントローラがオフラインになった場合の処理を行い、ポインティング リモコンなど複数のコントローラ タイプからの入力をサポートする必要があります。
D-pad の最低限の操作
TV デバイスのデフォルトのコントローラは D-pad です。一般に、アプリは、上、下、左、右、選択、戻る、ホームボタンのみを備えたリモコンで操作できなければなりません。アプリが通常は追加のコントロールを備えたゲーム コントローラを必要とするゲームである場合は、これらの D-pad コントロールのみでゲームプレイをサポートするようにしてください。それ以外の場合は、コントローラが必要であることをユーザーに警告し、D-pad コントローラを使用してゲームを正常に終了できるようにします。
テレビ デバイスの D-pad コントローラによるナビゲーションについて詳しくは、テレビのナビゲーションをご覧ください。
コントローラの接続解除を処理する
テレビのコントローラは Bluetooth デバイスであることが多く、定期的にスリープモードに入ってテレビデバイスから切断することで、電力を節約しようとすることがあります。つまり、再接続イベントを処理するように構成されていないアプリは、中断または再起動される可能性があります。これらのイベントは、次のいずれかの状況で発生する可能性があります。
- 数分間の動画を再生している間、D-pad またはゲーム コントローラがスリープモードに入り、テレビデバイスから切断され、後で再接続されることがあります。
- ゲームプレイ中に、まだ接続されていないゲーム コントローラを使用して新しいプレーヤーがゲームに参加する可能性があります。
- ゲームプレイ中に、プレーヤーがゲームを終了してゲーム コントローラを切断することがあります。
切断イベントと再接続イベントの対象となる TV アプリのアクティビティは、アプリ マニフェストで再接続イベントを処理するように構成する必要があります。次のコードサンプルは、キーボードやナビゲーション デバイスの接続、切断、再接続などの構成変更を処理するようにアクティビティを有効にする方法を示しています。
<activity
android:name="com.example.android.TvActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|navigation"
android:theme="@style/Theme.Leanback">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
...
</activity>
この構成変更により、アプリは再接続イベントを通じて実行を継続できます。Android フレームワークによって再起動されることはありません。これはユーザー エクスペリエンスの低下につながります。
さまざまな D-pad 入力を処理する
テレビ デバイスのユーザーは、テレビで使用するコントローラを複数種類持っている可能性があります。たとえば、ユーザーは基本的な D-pad コントローラ、ポインタ リモコン、ゲーム コントローラを使用している可能性があります。ゲーム コントローラが D-pad 機能に使用されるときに提供するキーコードは、基本的な D-pad が送信するキーコードと異なる場合があります。
D-pad 入力のバリエーションを処理して、ユーザーがアプリを操作するためにコントローラを切り替える必要がないようにします。入力バリエーションの処理について詳しくは、方向パッドの入力を処理するをご覧ください。
ポインター リモコンをサポート
一部のテレビ デバイスは、ポインタ リモコン(エアマウスやタッチセンサー式の方向パッド(トラックパッド)付きリモコンなど)をサポートしています。ポインタ リモコンをサポートすると、ユーザーはポイントアンドクリック、カーソル合わせ、スワイプ、ドラッグの操作を使用してアプリを操作できるようになり、互換性のあるハードウェアでスムーズな操作性を実現しながら、D-pad との完全な互換性を維持できます。
マニフェストでポインタ リモコンのサポートを宣言する
アプリがポインタとタッチ入力で操作可能であることを示すには、アプリ マニフェストで android.software.leanback.supports_touch メタデータを true に設定します。
<manifest ...>
<!-- Signal whether the app is adaptive or built just for TV -->
<uses-feature
android:name="android.software.leanback"
android:required="true|false" />
<!-- Ensure the app can be installed on conventional TVs -->
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<!-- Signal whether the app supports pointer remotes -->
<meta-data
android:name="android.software.leanback.supports_touch"
android:value="true" />
<application ...>
...
</application>
</manifest>
クリック、カーソル合わせ、スクロール操作に対応している
ポインタ リモコンをサポートする場合は、次の操作でカーソルとタッチ入力に UI コンポーネントが適切に応答することを確認してください。
- クリックと選択: フォーカス可能で選択可能なすべての UI 要素は、ポインタ リモコンでクリック可能でなければなりません。これは、D-pad 選択(
KEYCODE_DPAD_CENTER)の動作と一致します。 - 視覚的なホバー状態: ポインタ カーソルが選択可能なアイテムの上に置かれたときに、明確な視覚的なホバー効果を表示します。
- Jetpack Compose:
Modifier.hoverable()を使用するか、InteractionSourceを使用してホバー状態を監視します。詳しくは、ユーザー操作を処理するをご覧ください。 - ビュー:
android:state_hovered="true"を使用して状態リスト ドローアブルでホバー状態を定義します。
- Jetpack Compose:
- スワイプとフリックによるスクロール: タッチ センサー付きの中央 D-pad ボタンでのスワイプまたはフリック ジェスチャーによってトリガーされる水平方向と垂直方向のスクロールは、スクロール可能なすべてのコンテンツでスムーズに動作しなければなりません。
- ドラッグ スクロール: ユーザーは、スクロール可能なコンテナを縦(上下)または横(左右)にドラッグしてスクロールできる必要があります。
- Jetpack Compose: 標準のスクロール可能なコンテナは、デフォルトでポインタとタッチによるスクロールをサポートしています。カスタム実装については、Compose のポインタ入力をご覧ください。
- ビュー: 標準のスクロール可能なビューは、デフォルトでタッチ スクロールをサポートしています。カスタム入力処理については、タッチと入力をご覧ください。
- メディア再生のスクラブ: メディア(テレビ番組や映画など)の再生中、ユーザーは再生進行状況バー(シークバー)をポイントしてクリックすることで過去または未来のタイムスタンプにジャンプしたり、進行状況バーをドラッグ(スクラブ)して特定の時間にシークしたりできる必要があります。
ボタンイベントを処理する
ユーザーがコントローラのボタンをクリックすると、アプリは KeyEvent を含むイベントを受け取ります。ボタンの意図された動作は、再生、一時停止、停止などのメディア イベントの場合もあれば、選択やナビゲーションなどのテレビタイプのイベントの場合もあります。優れたユーザー エクスペリエンスを提供するため、コントローラのボタンに一貫した動作を割り当てます。
TV UI イベント
次の表に示すように、KeyEvent タイプを生成するボタンにテレビ UI の動作を割り当てます。
KeyEvent |
動作 |
|---|---|
KEYCODE_BUTTON_B、KEYCODE_BACK |
戻る |
KEYCODE_BUTTON_SELECT、KEYCODE_BUTTON_A、KEYCODE_ENTER、KEYCODE_DPAD_CENTER、KEYCODE_NUMPAD_ENTER |
選択 |
KEYCODE_DPAD_UP、KEYCODE_DPAD_DOWN、KEYCODE_DPAD_LEFT、KEYCODE_DPAD_RIGHT |
ナビゲーション |
メディア イベント
ユーザーがメディアを視聴しているときは、次の表に示すように、KeyEvent タイプを生成するボタンに動作を割り当てます。アプリが MediaSession を制御している場合は、MediaControllerAdapter を使用して、表に示す MediaControllerCompat.TransportControls メソッドのいずれかを呼び出します。このコンテキストでは、選択ボタンは再生ボタンまたは一時停止ボタンとして機能します。
KeyEvent |
TransportControls 呼び出し | 動作 |
|---|---|---|
BUTTON_SELECT、BUTTON_A、ENTER、DPAD_CENTER、KEYCODE_NUMPAD_ENTER |
play() |
再生 |
BUTTON_START、BUTTON_SELECT、BUTTON_A、ENTER、DPAD_CENTER、KEYCODE_NUMPAD_ENTER |
pause() |
一時停止 |
BUTTON_R1 |
skipToNext() |
次へスキップ |
BUTTON_L1 |
skipToPrevious() |
前へスキップ |
DPAD_RIGHT、BUTTON_R2、AXIS_RTRIGGER、AXIS_THROTTLE |
fastForward() |
早送り |
DPAD_LEFT、BUTTON_L2、AXIS_LTRIGGER、AXIS_BRAKE |
rewind() |
巻き戻し |
| なし | stop() |
停止 |
適切な「戻る」ボタンの動作を提供する
戻るボタンは切り替えとして機能してはなりません。たとえば、メニューを開く操作と閉じる操作の両方に使用しないでください。このボタンは、プレーヤーがアクセスした前の画面をパンくずリスト形式で戻る場合にのみ使用します。
戻るボタンは線形の後方ナビゲーションのみを行うため、別のボタンで開いたアプリ内メニューを閉じてアプリに戻るために使用できます。戻るボタンを連続して押すと、最終的には必ず Android TV のホーム画面に戻る必要があります。例: ゲームプレイ > ゲームの一時停止画面 > ゲームのメイン画面 > Android TV のホーム画面、またはテレビ番組の再生 > テレビアプリのメイン画面
Android TV のホーム画面。
ナビゲーションの設計について詳しくは、戻るナビゲーションと上へナビゲーションの設計をご覧ください。実装については、適切な「戻る」ナビゲーションを提供するをご覧ください。
ゲームのコントローラを処理する
Android TV 向けにゲームを構築する際は、標準のテレビ リモコンと専用のゲーム コントローラの両方で動作するようにコントロール スキームを設計してください。
D-pad 操作をサポートする
Android TV デバイスではこのコントロール セットがデフォルトであるため、D-pad コントロールを中心にコントロール スキームを計画します。プレーヤーは、ゲームのあらゆる面で D-pad を使用できる必要があります。ゲームプレイの中心的要素の操作だけでなく、メニューや広告のナビゲーションも D-pad で行えるようにする必要があります。そのため、Android TV ゲームで「ここをタップして続行」のようなタッチ インターフェースを参照する文言を使用しないようにしてください。
コントローラでのプレイヤーの操作をどのように形作るかは、優れたユーザー エクスペリエンスを実現するうえで重要です。次に紹介するおすすめの方法をご覧ください。
- コントローラの要件を事前に伝える: Google Play の説明を使用して、コントローラに関する期待値をプレイヤーに伝えます。ゲームが D-pad のみではなくジョイスティック付きのゲームパッドに適している場合は、そのことを明記します。ゲームに適していないコントローラを使用しているプレーヤーは、ゲームの評価を低くする可能性があります。
- ボタン マッピングの一貫性を保つ: 直感的なボタン マッピングは、優れたユーザー エクスペリエンスを実現するうえで重要です。たとえば、A ボタンで承諾、B ボタンでキャンセルするなど、一般的な操作方法に準拠します。ユーザーがボタンを再マッピングできるようにすることで、柔軟性を提供することもできます。ボタン マッピングについて詳しくは、コントローラの操作を処理するをご覧ください。
- コントローラの機能を検出し、それに応じて調整する: コントローラの機能についてコントローラにクエリを実行し、コントローラとゲームの適合性を最適化します。たとえば、プレーヤーがコントローラを空中で振ってオブジェクトを操縦することを想定していても、プレーヤーのコントローラに加速度計とジャイロスコープのハードウェアが搭載されていない場合、振っても機能しません。コントローラをクエリし、モーション検知(機能)がサポートされていない場合は、利用可能な代替の制御スキームに切り替えます。コントローラの機能のクエリについて詳しくは、複数の Android バージョンにまたがるコントローラのサポートをご覧ください。
適切なボタンを使用する
ゲーム コントローラの中には、スタートボタン、検索ボタン、メニューボタンがないものもあります。UI がこれらのボタンの使用に依存していないことを確認してください。
複数のコントローラを処理する
複数のプレーヤーがそれぞれコントローラを使用してゲームをプレイしている場合は、各プレーヤーとコントローラのペアをマッピングすることが重要です。コントローラ番号の識別を実装する方法については、getControllerNumber() をご覧ください。
コントローラの接続解除を処理する
ゲームプレイ中にコントローラが切断された場合は、ゲームを一時停止し、切断されたプレーヤーにコントローラの再接続を促すダイアログを表示します。
また、ダイアログでトラブルシューティングのヒントも提供します。たとえば、プレーヤーに「Bluetooth 接続を確認してください」と伝えるようにします。入力デバイスのサポートの実装について詳しくは、コントローラの操作を処理すると Bluetooth の概要をご覧ください。
コントローラの操作説明を表示する
ゲームでゲーム コントロールの説明を視覚的に提供する場合は、特定のブランドとは関係のないコントローラの画像を使用し、Android と互換性のあるボタンのみを含めます。
Android 対応コントローラのサンプル画像については、Android TV ゲームパッド テンプレート(ZIP)をダウンロードしてください。図 1 に示すように、黒い背景に白いコントローラ、白い背景に黒いコントローラが PNG ファイルと Adobe® Illustrator® ファイルで含まれています。