ホーム画面のチャンネル

Android TV のホーム画面(または単にホーム画面)には、以下の操作を行うための UI が用意されています。 おすすめのコンテンツがチャンネル番組の表として表示される。各行がチャンネルです。チャンネルには、そのチャンネルで利用可能なすべてのプログラムのカードが含まれています。

TV のホーム画面

このドキュメントでは、ユーザーに最高のエクスペリエンスを提供できるように、ホーム画面へのチャンネルとプログラムの追加、コンテンツの更新、ユーザー アクションの処理をする方法を示します。(API についてさらに詳しく知りたい場合は、 ホーム画面の Codelab I/O 2017 Android TV セッションをご覧ください)。

注: おすすめチャンネルをご利用いただける国は、次のとおりです。 Android 8.0(API レベル 26)以降。これを使用して Android 8.0(API レベル 26)以降で実行されるアプリの推奨事項宛先 以前のバージョンの Android で実行されているアプリ、 使用する必要があります。 推奨事項の行 してください。

ホーム画面の UI

アプリは、新しいチャンネルの作成、チャンネル内のプログラムの追加、削除、更新、チャンネル内のプログラムの順序の管理を行うことができます。 たとえば、「新作」というチャンネルを作成して、新たに利用可能になったプログラムのカードを表示できます。

アプリでは、ホーム画面に表示されるチャンネルの順序を制御できません。アプリが新しいチャンネルを作成すると、それをホーム画面がチャンネル リストの下部に追加します。ユーザーは、チャンネルの並べ替えと、表示非表示の切り替えができます。

Watch Next チャンネル

Watch Next チャンネルは、ホーム画面の クリックします。このチャンネルはシステムが作成し管理します。アプリに Watch Next チャンネルに移行されます詳しくは、プログラムを追加する Watch Next チャンネルをご覧ください。

アプリ チャンネル

アプリが作成するチャンネルは、すべて次のライフサイクルに従います。

  1. ユーザーがアプリでチャンネルを発見し、それをホーム画面に追加するよう要求する。
  2. アプリがチャンネルを作成し、TvProvider に追加する(この時点ではチャンネルは表示されない)。
  3. アプリがシステムにチャンネルを表示するよう要求する。
  4. システムが、新しいチャンネルを承認するようユーザーに要求する。
  5. ホーム画面の最後の行に新しいチャンネルが表示される。

デフォルト チャンネル

アプリは、ユーザーがホーム画面に追加するチャンネルをいくつでも提供できます。通常、ユーザーは チャンネルを選択して承認すると、ホーム画面に表示されます。アプリごとに、デフォルト チャンネルを 1 つ作成するオプションがあります。 デフォルト チャンネルは、ホーム画面に自動的に表示される特別なチャンネルです。ユーザーは、 明示的にリクエストします。

前提条件

Android TV のホーム画面では、Android の TvProvider API を使用して、アプリが作成するチャンネルとプログラムを管理します。 プロバイダのデータにアクセスするには、アプリのマニフェストに次の権限を追加します。

<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />

TvProvider サポート ライブラリの使用により、プロバイダの使用が簡単になります。次のように、build.gradle ファイルの依存関係に追加してください。

Groovy

implementation 'androidx.tvprovider:tvprovider:1.0.0'

Kotlin

implementation("androidx.tvprovider:tvprovider:1.0.0")

チャンネルとプログラムを操作するには、次に示すサポート ライブラリのインポートをソースコードに含めます。

Kotlin

import android.support.media.tv.Channel
import android.support.media.tv.TvContractCompat
import android.support.media.tv.ChannelLogoUtils
import android.support.media.tv.PreviewProgram
import android.support.media.tv.WatchNextProgram

Java

import android.support.media.tv.Channel;
import android.support.media.tv.TvContractCompat;
import android.support.media.tv.ChannelLogoUtils;
import android.support.media.tv.PreviewProgram;
import android.support.media.tv.WatchNextProgram;

チャンネル

アプリが作成した最初のチャンネルが、デフォルト チャンネルになります。デフォルト チャンネルは、ホーム画面に自動的に表示されます。作成した他のすべてのチャンネルは、ユーザーが選択し承認するまでホーム画面に表示されません。

チャンネルを作成する

アプリが新しく追加されたチャンネルの表示をシステムに要求するのは、フォアグラウンドで動作している場合だけにする必要があります。こうすることで、ユーザーが別のアプリを実行しているときに、チャンネルを追加するための承認を要求するダイアログをアプリが表示することがなくなります。バックグラウンドでの動作中にチャンネルを追加しようとすると、アクティビティの onActivityResult() メソッドがステータス コード RESULT_CANCELED を返します。

チャンネルを作成する手順は次のとおりです。

  1. チャンネル ビルダーを作成し、その属性を設定します。なお、 チャネル タイプは TYPE_PREVIEW にする必要があります。さらに追加 属性を指定します。

    Kotlin

    val builder = Channel.Builder()
    // Every channel you create must have the type TYPE_PREVIEW
    builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
            .setDisplayName("Channel Name")
            .setAppLinkIntentUri(uri)
    

    Java

    Channel.Builder builder = new Channel.Builder();
    // Every channel you create must have the type TYPE_PREVIEW
    builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
            .setDisplayName("Channel Name")
            .setAppLinkIntentUri(uri);
    
  2. チャンネルをプロバイダに挿入します。

    Kotlin

    var channelUri = context.contentResolver.insert(
            TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues())
    

    Java

    Uri channelUri = context.getContentResolver().insert(
            TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());
    
  3. チャンネルにプログラムを追加するには、チャンネル ID を保存する必要があります 後で説明します返された URI からチャンネル ID を抽出します。

    Kotlin

    var channelId = ContentUris.parseId(channelUri)
    

    Java

    long channelId = ContentUris.parseId(channelUri);
    
  4. チャンネルのロゴを追加する必要があります。Uri または Bitmap を使用します。ロゴ アイコンは 80 dp x 80 dp とし、不透明にする必要があります。このボタンは 円形マスク:

    TV ホーム画面アイコンマスク

    Kotlin

    // Choose one or the other
    storeChannelLogo(context: Context, channelId: Long, logoUri: Uri) // also works if logoUri is a URL
    storeChannelLogo(context: Context, channelId: Long, logo: Bitmap)
    

    Java

    // Choose one or the other
    storeChannelLogo(Context context, long channelId, Uri logoUri); // also works if logoUri is a URL
    storeChannelLogo(Context context, long channelId, Bitmap logo);
    
  5. デフォルト チャンネルを作成する(省略可): アプリが最初のチャンネルを作成したとき 公開したい場合は デフォルト チャンネルにして、ホームに表示される すぐに結果が表示されます。他のユーザーが作成したチャンネル ユーザーが明示的に指定しない限り、 選択されます。

    Kotlin

    TvContractCompat.requestChannelBrowsable(context, channelId)
    

    Java

    TvContractCompat.requestChannelBrowsable(context, channelId);
    

  6. アプリを開く前にデフォルト チャンネルを表示します。Google Chat では この動作を実現するには、BroadcastReceiver android.media.tv.action.INITIALIZE_PROGRAMS アクションがあります。これにより、 次のメソッドがインストール後に送信されます。
    <receiver
      android:name=".RunOnInstallReceiver"
      android:exported="true">
        <intent-filter>
          <action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" />
          <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    
    開発中にアプリをサイドローディングする場合は、次の方法でテストできます。 adb 経由でインテントをトリガーできます。 your.package.name/.YourReceiverName は、お客様のアプリの BroadcastReceiver:

    adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \
        your.package.name/.YourReceiverName
    

    まれに、ユーザーがブロードキャストを同時に受信することがあります。 アプリを起動します。コードでデフォルト チャンネルの追加を試行していないことを確認する できます。

チャンネルを更新する

チャンネルの更新は、チャンネルの作成とよく似ています。

別の Channel.Builder を使用して、変更する必要がある属性を設定します。

ContentResolver を使用して、チャンネルを更新します。最初にチャンネルを追加したときに保存したチャンネル ID を使用します。

Kotlin

context.contentResolver.update(
        TvContractCompat.buildChannelUri(channelId),
        builder.build().toContentValues(),
        null,
        null
)

Java

context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId),
    builder.build().toContentValues(), null, null);

チャンネルのロゴを更新するには、storeChannelLogo() を使用します。

チャンネルを削除する

Kotlin

context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)

Java

context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);

プログラム

アプリ チャンネルにプログラムを追加する

PreviewProgram.Builder を作成し、その属性を設定します。

Kotlin

val builder = PreviewProgram.Builder()
builder.setChannelId(channelId)
        .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
        .setTitle("Title")
        .setDescription("Program description")
        .setPosterArtUri(uri)
        .setIntentUri(uri)
        .setInternalProviderId(appProgramId)

Java

PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(channelId)
        .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
        .setTitle("Title")
        .setDescription("Program description")
        .setPosterArtUri(uri)
        .setIntentUri(uri)
        .setInternalProviderId(appProgramId);

プログラムのタイプに応じて、さらに属性を追加します(属性を プログラムのタイプごとに利用可能な場合は、以下のをご覧ください)。

プログラムをプロバイダに挿入します。

Kotlin

var programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
        builder.build().toContentValues())

Java

Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
      builder.build().toContentValues());

後で参照できるようにプログラム ID を取得します。

Kotlin

val programId = ContentUris.parseId(programUri)

Java

long programId = ContentUris.parseId(programUri);

プログラムを Watch Next チャンネルに追加する

プログラムを Watch Next チャンネルに挿入するには、プログラムを Watch Next に追加するをご覧ください。 次のチャンネル

プログラムを更新する

プログラムの情報は変更できます。たとえば、映画のレンタル価格を更新したい場合や、ユーザーが視聴したプログラムの量を示す進行状況バーを更新したい場合があります。

PreviewProgram.Builder を使用して、変更する必要がある属性を設定します。 次に、getContentResolver().update を呼び出してプログラムを更新します。プログラムが最初に追加されたときに保存したプログラム ID を指定します。

Kotlin

context.contentResolver.update(
        TvContractCompat.buildPreviewProgramUri(programId),
                builder.build().toContentValues(), null, null
)

Java

context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId),
    builder.build().toContentValues(), null, null);

プログラムを削除する

Kotlin

context.contentResolver
        .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)

Java

context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);

ユーザー操作の処理

アプリは、チャンネルを表示および追加するための UI を提供することで、ユーザーがコンテンツを見つけられるようにします。 また、チャンネルがホーム画面に表示された後、アプリでチャンネルに対する操作を処理する必要があります。

チャンネルの発見と追加

アプリでは、ユーザーがチャンネルの選択と追加を行える UI 要素(たとえば、チャンネルの追加を要求するボタン)を提供できます。

ユーザーが特定のチャンネルを要求した後、次のコードを実行して、ホーム画面 UI に追加する許可をユーザーから得ます。

Kotlin

val intent = Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE)
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId)
try {
  activity.startActivityForResult(intent, 0)
} catch (e: ActivityNotFoundException) {
  // handle error
}

Java

Intent intent = new Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE);
intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId);
try {
   activity.startActivityForResult(intent, 0);
} catch (ActivityNotFoundException e) {
  // handle error
}

ユーザーにチャンネルの承認を求めるダイアログが表示されます。 次のアクティビティの onActivityResult メソッド内でこの要求の結果を処理します: Activity.RESULT_CANCELED あるいは Activity.RESULT_OK

Android TV ホーム画面イベント

ユーザーがアプリによって公開されたプログラム / チャンネルを操作すると、ホーム画面はアプリにインテントを送信します。

  • ユーザーがチャンネルのロゴを選択すると、ホーム画面はチャンネルの APP_LINK_INTENT_URI 属性に保存されている Uri をアプリに送信します。アプリは、メイン UI または選択したチャンネルに関連するビューを起動します。
  • ユーザーがプログラムを選択すると、ホーム画面はプログラムの INTENT_URI 属性に保存されている Uri をアプリに送信します。アプリは、選択されたコンテンツを再生しなければなりません。
  • ユーザーは、興味がなくなったプログラムをホーム画面の UI から削除することを要求できます。システムが UI からプログラムを削除し、プログラムを所有するアプリにプログラム ID を指定してインテント(android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED あるいは android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED)を送信します。受け取ったアプリは、プロバイダからアプリを削除しなければならず、再度挿入することも行わないでください。

ホーム画面がユーザーの操作に対して送信する Uris すべてにインテント フィルタを作成してください。

<receiver
   android:name=".WatchNextProgramRemoved"
   android:enabled="true"
   android:exported="true">
   <intent-filter>
       <action android:name="android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
   </intent-filter>
</receiver>

おすすめの方法

  • 多くの TV アプリがユーザーのログインを必要とします。この場合は、BroadcastReceiver android.media.tv.action.INITIALIZE_PROGRAMS をリッスンするモデルは、 チャンネル コンテンツを認証します。たとえば、最初に おすすめのコンテンツや 現在人気のコンテンツを表示しますユーザーがログインすると カスタマイズされたコンテンツを表示できます。これはアプリのアップセルの チャンスです できます。
  • アプリがフォアグラウンドでなく、チャンネルやアプリをアップデートする必要がある場合、 JobScheduler を使用して処理のスケジュールを設定します(参照: JobSchedulerJobService を参照)。
  • アプリが正常に動作しない場合、システムはアプリのプロバイダの権限を取り消すことがあります (プロバイダに継続的にデータを大量送信するなど)。必ず プロバイダにアクセスするコードを try-catch 句でラップし、 例外があります。
  • 番組やチャンネルを更新する前に、 データの更新と調整が必要になりますたとえば、Terraform でインフラストラクチャを ユーザーが UI から削除したいプログラム実行中のバックグラウンド ジョブを使用して は、既存のサービス アカウントをクエリした後、プロバイダにデータを挿入/更新します。 チャンネルの承認をリクエストできますこのジョブは アプリが起動し、アプリのデータを更新する必要があるとき。

    Kotlin

    context.contentResolver
      .query(
          TvContractCompat.buildChannelUri(channelId),
              null, null, null, null).use({
                  cursor-> if (cursor != null and cursor.moveToNext()) {
                               val channel = Channel.fromCursor(cursor)
                               if (channel.isBrowsable()) {
                                   //update channel's programs
                               }
                           }
              })
    

    Java

    try (Cursor cursor = context.getContentResolver()
          .query(
              TvContractCompat.buildChannelUri(channelId),
              null,
              null,
              null,
              null)) {
                  if (cursor != null && cursor.moveToNext()) {
                      Channel channel = Channel.fromCursor(cursor);
                      if (channel.isBrowsable()) {
                          //update channel's programs
                      }
                  }
              }
    
  • すべての画像(ロゴ、アイコン、コンテンツ画像)に一意な URI を使用します。画像を更新するときには、必ず別の URI を使用してください。画像はすべてキャッシュに保存されます。画像を変更したときに URI を変更しないと、古い画像が表示されたままになります。

  • WHERE 句は許可されておらず、WHERE 句を使用してプロバイダを呼び出すとセキュリティ例外がスローされることに注意してください。

属性

このセクションでは、チャンネルとプログラムの属性について個別に説明します。

チャンネルの属性

すべてのチャンネルに次の属性を指定する必要があります。

属性 備考
TYPE TYPE_PREVIEW に設定します。
DISPLAY_NAME チャンネルの名前を設定します。
APP_LINK_INTENT_URI ユーザーがチャンネルのロゴを選択すると、システムはチャンネルに関連するコンテンツを提示するアクティビティを開始するインテントを送信します。この属性に、そのアクティビティのインテント フィルタで使用される URI を設定します。

さらに、チャンネルには、アプリの内部使用のために予約された 6 つのフィールドもあります。これらのフィールドにキーやその他の値を保存して、チャンネルからアプリの内部データ構造への対応付けに使用できます。

  • INTERNAL_PROVIDER_ID
  • INTERNAL_PROVIDER_DATA
  • INTERNAL_PROVIDER_FLAG1
  • INTERNAL_PROVIDER_FLAG2
  • INTERNAL_PROVIDER_FLAG3
  • INTERNAL_PROVIDER_FLAG4

プログラムの属性

プログラムの属性については、タイプごとの個々のページをご覧ください。

サンプルコード

ホーム画面の操作を処理し、Android TV ホーム画面にチャンネルとプログラムを追加するアプリを作成する方法について詳しくは、ホーム画面の Codelab をご覧ください。