Android TV のホーム画面(または単にホーム画面)には、以下の操作を行うための UI が用意されています。 おすすめのコンテンツがチャンネルと番組の表として表示される。各行がチャンネルです。チャンネルには、そのチャンネルで利用可能なすべてのプログラムのカードが含まれています。
このドキュメントでは、ユーザーに最高のエクスペリエンスを提供できるように、ホーム画面へのチャンネルとプログラムの追加、コンテンツの更新、ユーザー アクションの処理をする方法を示します。(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 チャンネルをご覧ください。
アプリ チャンネル
アプリが作成するチャンネルは、すべて次のライフサイクルに従います。
- ユーザーがアプリでチャンネルを発見し、それをホーム画面に追加するよう要求する。
- アプリがチャンネルを作成し、
TvProvider
に追加する(この時点ではチャンネルは表示されない)。 - アプリがシステムにチャンネルを表示するよう要求する。
- システムが、新しいチャンネルを承認するようユーザーに要求する。
- ホーム画面の最後の行に新しいチャンネルが表示される。
デフォルト チャンネル
アプリは、ユーザーがホーム画面に追加するチャンネルをいくつでも提供できます。通常、ユーザーは チャンネルを選択して承認すると、ホーム画面に表示されます。アプリごとに、デフォルト チャンネルを 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
を返します。
チャンネルを作成する手順は次のとおりです。
チャンネル ビルダーを作成し、その属性を設定します。なお、 チャネル タイプは
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);チャンネルをプロバイダに挿入します。
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());
-
チャンネルにプログラムを追加するには、チャンネル ID を保存する必要があります 後で説明します返された URI からチャンネル ID を抽出します。
Kotlin
var channelId = ContentUris.parseId(channelUri)
Java
long channelId = ContentUris.parseId(channelUri);
チャンネルのロゴを追加する必要があります。
Uri
またはBitmap
を使用します。ロゴ アイコンは 80 dp x 80 dp とし、不透明にする必要があります。このボタンは 円形マスク: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);
デフォルト チャンネルを作成する(省略可): アプリが最初のチャンネルを作成したとき 公開したい場合は デフォルト チャンネルにして、ホームに表示される すぐに結果が表示されます。他のユーザーが作成したチャンネル ユーザーが明示的に指定しない限り、 選択されます。
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)
Java
TvContractCompat.requestChannelBrowsable(context, channelId);
- アプリを開く前にデフォルト チャンネルを表示します。Google Chat では
この動作を実現するには、
BroadcastReceiver
android.media.tv.action.INITIALIZE_PROGRAMS
アクションがあります。これにより、 次のメソッドがインストール後に送信されます。 開発中にアプリをサイドローディングする場合は、次の方法でテストできます。 adb 経由でインテントをトリガーできます。 your.package.name/.YourReceiverName は、お客様のアプリの<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>
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
を使用して処理のスケジュールを設定します(参照: JobScheduler や JobService を参照)。 - アプリが正常に動作しない場合、システムはアプリのプロバイダの権限を取り消すことがあります (プロバイダに継続的にデータを大量送信するなど)。必ず プロバイダにアクセスするコードを 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 をご覧ください。