TV コントローラを管理する

テレビデバイスでは、アプリを操作するために、基本的なリモコン、ポインター リモコン、ゲーム コントローラなどのセカンダリ ハードウェア デバイスが必要です。一貫したユーザー エクスペリエンスを提供するには、アプリが方向パッド(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 との完全な互換性を維持しながら、対応ハードウェアでよりスムーズな操作性を実現できます。

マニフェストでポインタ リモコンのサポートを宣言する

アプリがポインタ入力とタップ入力でナビゲーション可能であることを示すには、<application> 要素内(またはアクティビティごとにサポートを構成する場合は個々の <activity> 要素内)で android.software.leanback.supports_touch <property> を 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" />
    <application ...>
        <!-- Signal whether the app supports pointer remotes -->
        <property
            android:name="android.software.leanback.supports_touch"
            android:value="true" />
        ...
    </application>
</manifest>

クリック、カーソル合わせ、スクロールの操作に対応している

ポインター リモコンをサポートする場合は、UI コンポーネントが次の操作でカーソル入力とタップ入力に適切に応答するようにします。

  • クリックと選択: フォーカス可能で選択可能なすべての UI 要素は、ポインタ リモコンでクリック可能で、D-pad 選択(KEYCODE_DPAD_CENTER)の動作と一致している必要があります。
    • Jetpack Compose: Modifier.clickable() 修飾子または pointerInput 修飾子を使用します。詳しくは、タップと長押しをご覧ください。
    • ビュー: ビューでのクリック イベントを処理します。詳細については、入力イベントの概要をご覧ください。
  • 視覚的なホバー状態: 選択可能なアイテムの上にポインタ カーソルが置かれていることを示す、明確な視覚的ホバー効果を提供します。
    • Jetpack Compose: Modifier.hoverable() を使用するか、InteractionSource を使用してホバー状態を監視します。詳細については、ユーザー操作を処理するをご覧ください。
    • ビュー: android:state_hovered="true" を含む状態リスト ドローアブルを使用して、ホバー状態を定義します。
  • スワイプとフリックによるスクロール: タッチ対応の中央 D-pad ボタンでのスワイプまたはフリック ジェスチャーによってトリガーされる水平方向と垂直方向のスクロールは、すべてのスクロール可能なコンテンツでスムーズに動作しなければなりません。
  • ドラッグ スクロール: ユーザーは、スクロール可能なコンテナをドラッグして、垂直方向(上下)または水平方向(左右)にスクロールできる必要があります。
    • Jetpack Compose: 標準のスクロール可能なコンテナは、デフォルトでポインタとタッチによるスクロールをサポートしています。カスタム実装については、Compose でのポインタ入力をご覧ください。
    • ビュー: 標準のスクロール可能なビューは、デフォルトでタッチ スクロールをサポートしています。カスタム入力処理については、タップと入力をご覧ください。
  • メディア再生のスクラブ: メディア(テレビ番組や映画など)の再生中、ユーザーは、再生進行状況バー(シークバー)をポイントしてクリックすることで、過去または未来のタイムスタンプにジャンプできる必要があります。また、進行状況バーに沿ってドラッグ(スクラブ)することで、特定の時間にシークできる必要があります。

ボタンイベントを処理する

ユーザーがコントローラのボタンをクリックすると、アプリは KeyEvent を含むイベントを受け取ります。ボタンの意図された動作は、再生、一時停止、停止などのメディア イベント、または選択やナビゲーションなどのテレビタイプのイベントです。優れたユーザー エクスペリエンスを提供するには、コントローラ ボタンに一貫した動作を割り当てます。

TV UI イベント

次の表に示すように、KeyEvent タイプを生成するボタンに TV 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 のホーム画面、またはテレビ番組の再生 > 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® ファイルとして提供されています。

**図 1.** Android TV ゲームパッド テンプレートを使用したコントローラの説明の例。