このガイドでは、Engage SDK を使用しておすすめの動画コンテンツを統合し、テレビ、モバイル、タブレットなどの Google サーフェス全体におすすめコンテンツを表示する手順を説明します。
おすすめコンテンツは、おすすめコンテンツ クラスタを利用して、複数のアプリの映画やテレビ番組を 1 つの UI グループに表示します。各デベロッパー パートナーは、各おすすめコンテンツ クラスタで最大 25 個のエンティティをブロードキャストできます。リクエストごとに最大 7 個のおすすめコンテンツ クラスタを指定できます。
事前作業
始める前に、次の手順を完了します。1. この統合でアプリが API レベル 19 以降をターゲットにしていることを確認します。
アプリに
com.google.android.engage
ライブラリを追加します。統合に使用する SDK は、モバイルアプリ用とテレビアプリ用の 2 つあります。
モバイルの場合
dependencies { implementation 'com.google.android.engage:engage-core:1.5.5 }
テレビ
dependencies { implementation 'com.google.android.engage:engage-tv:1.0.2 }
AndroidManifest.xml
ファイルで Engage サービス環境を本番環境に設定します。モバイル APK の場合
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
For tv apk
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
フォアグラウンド サービスで公開を実行する。
推奨事項データを 1 日に 1 回以下、次のいずれかによって公開します。
- ユーザーがその日に初めてログインした日時。(または)
- ユーザーがアプリの操作を開始したとき。
統合
AppEngagePublishClient
は推奨事項クラスタを公開します。publishRecommendationClusters
メソッドを使用して、おすすめコンテンツ オブジェクトを公開します。
isServiceAvailable()
2 を使用して、統合に使用できるサービスがあるかどうかを確認します。
val client = AppEngagePublishClient(context)
client.isServiceAvailable().addOnCompleteListener { task ->
if (task.isSuccessful) {
// Handle IPC call success
if(task.result) {
// Service is available on the device, proceed with content publish
// calls.
client.publishRecommendationClusters(recommendationRequest)
} else {
// Service is not available
}
} else {
// The IPC call itself fails, proceed with error handling logic here,
// such as retry.
}
}
おすすめコンテンツ クラスタと公開リクエスト
クラスタは、エンティティの論理グループです。次のコードサンプルでは、設定に基づいてクラスタを構築する方法と、すべてのクラスタの公開リクエストを作成する方法について説明します。
// cluster for popular movies
val recommendationCluster1 = RecommendationCluster
.Builder()
.addEntity(movie)
.addEntity(tvShow)
.setTitle("Popular Movies")
.build()
// cluster for top searches
val recommendationCluster2 = RecommendationCluster
.Builder()
.addEntity(movie)
.addEntity(tvShow)
.setTitle("Top Searches")
.build()
// creating a publishing request
val recommendationRequest = PublishRecommendationClustersRequest
.Builder()
.setSyncAcrossDevices(true)
.setAccountProfile(accountProfile)
.addRecommendationCluster(recommendationCluster1)
.addRecommendationCluster(recommendationCluster2)
.build()
アカウント プロファイルを作成する
Google TV でパーソナライズされたエクスペリエンスを利用できるようにするには、アカウントとプロフィール情報を提供します。AccountProfile
を使用して、次の情報を指定します。
- アカウント ID: アプリケーション内のユーザーのアカウントを表す一意の識別子。これは実際のアカウント ID でも、適切に難読化されたバージョンでもかまいません。
- プロフィール ID(省略可): アプリケーションが 1 つのアカウント内の複数のプロフィールをサポートしている場合は、特定のユーザー プロフィールの一意の ID を指定します。
- ロケール(省略可): 必要に応じて、ユーザーの優先言語を指定できます。このフィールドは、
RecommendationRequest
でMediaActionFeedEntity
を送信する場合に便利です。
// If app only supports account
val accountProfile = AccountProfile.Builder()
.setAccountId("account_id")
.build();
// If app supports both account and profile
val accountProfile = AccountProfile.Builder()
.setAccountId("account_id")
.setProfileId("profile_id")
.build();
// set Locale
val accountProfile = AccountProfile.Builder()
.setAccountId("account_id")
.setProfileId("profile_id")
.setLocale("en-US")
.build();
サービスがリクエストを受信すると、1 つのトランザクション内で次のアクションが行われます。
- デベロッパー パートナーが提供した既存の
RecommendationsCluster
データが削除されます。 - リクエストのデータが解析されて、更新された
RecommendationsCluster
に保存されます。エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
クロスデバイスの同期
SyncAcrossDevices
フラグは、ユーザーのおすすめコンテンツ クラスタ データが Google TV と共有され、テレビ、スマートフォン、タブレットなどのデバイスで利用可能かどうかを制御します。推奨事項が機能するには、true に設定する必要があります。
同意を得る
メディア アプリには、クロスデバイス同期を有効または無効にするための明確な設定が必要です。ユーザーにメリットを説明し、ユーザーの設定を 1 回保存して、publishRecommendations
リクエストで適宜適用します。クロスデバイス機能を最大限に活用するには、アプリがユーザーの同意を得ていることを確認し、SyncAcrossDevices
を true
に有効にします。
動画検出データを削除する
標準の 60 日間の保持期間の前に Google TV サーバーからユーザーのデータを手動で削除するには、client.deleteClusters()
メソッドを使用します。リクエストを受信すると、サービスはアカウント プロフィールまたはアカウント全体の既存の動画検出データをすべて削除します。
DeleteReason
列挙型は、データ削除の理由を定義します。次のコードは、ログアウト時におすすめを削除します。
// If the user logs out from your media app, you must make the following call
// to remove recommendations data from the current google TV device,
// otherwise, the recommendations data persists on the current
// google TV device until 60 days later.
client.deleteClusters(
new DeleteClustersRequest.Builder()
.setAccountProfile(AccountProfile())
.setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
.build()
)
// If the user revokes the consent to share data with Google TV,
// you must make the following call to remove recommendations data from
// all current google TV devices. Otherwise, the recommendations data persists
// until 60 days later.
client.deleteClusters(
new DeleteClustersRequest.Builder()
.setAccountProfile(AccountProfile())
.setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT)
.build()
)
エンティティを作成する
この SDK では、各アイテムタイプを表すさまざまなエンティティを定義しています。おすすめコンテンツ クラスタでは、次のエンティティがサポートされています。
MediaActionFeedEntity
MovieEntity
TvShowEntity
説明
各エンティティに簡単な説明を入力します。この説明は、ユーザーがエンティティにカーソルを合わせたときに表示され、詳細情報を提供します。
プラットフォーム固有の playBack URI
サポートされているプラットフォーム(Android TV、Android、iOS)ごとに再生 URI を作成します。これにより、システムはそれぞれのプラットフォームで動画を再生するための適切な URI を選択できます。
すべてのプラットフォームで再生 URI が同じというまれなケースでは、すべてのプラットフォームで同じ URI を使用します。
// Required. Set this when you want recommended entities to show up on
// Google TV
val playbackUriTv = PlatformSpecificUri
.Builder()
.setPlatformType(PlatformType.TYPE_ANDROID_TV)
.setActionUri(Uri.parse("https://www.example.com/entity_uri_for_tv"))
.build()
// Optional. Set this when you want recommended entities to show up on
// Google TV Android app
val playbackUriAndroid = PlatformSpecificUri
.Builder()
.setPlatformType(PlatformType.TYPE_ANDROID_MOBILE)
.setActionUri(Uri.parse("https://www.example.com/entity_uri_for_android"))
.build()
// Optional. Set this when you want recommended entities to show up on
// Google TV iOS app
val playbackUriIos = PlatformSpecificUri
.Builder()
.setPlatformType(PlatformType.TYPE_IOS)
.setActionUri(Uri.parse("https://www.example.com/entity_uri_for_ios"))
.build()
val platformSpecificPlaybackUris =
Arrays.asList(playbackUriTv, playbackUriAndroid, playbackUriIos)
// Provide appropriate rating for the system.
val contentRating = new RatingSystem
.Builder()
.setAgencyName("MPAA")
.setRating("PG-13")
.build()
ポスター画像
ポスター画像には URI とピクセル単位のサイズ(高さと幅)が必要です。複数のポスター画像を指定してさまざまなフォーム ファクタをターゲットに設定しますが、特に Google のエンターテイメント スペース内で「おすすめ」エンティティを正しく表示するには、すべての画像でアスペクト比が 16:9 に保たれ、高さが 200 ピクセル以上であることを確認してください。高さが 200 ピクセル未満の画像は表示されない場合があります。
Image image1 = new Image.Builder()
.setImageUri(Uri.parse("http://www.example.com/entity_image1.png");)
.setImageHeightInPixel(300)
.setImageWidthInPixel(169)
.build()
Image image2 = new Image.Builder()
.setImageUri(Uri.parse("http://www.example.com/entity_image2.png");)
.setImageHeightInPixel(640)
.setImageWidthInPixel(360)
.build()
// And other images for different form factors.
val images = Arrays.asList(image1, image2)
推奨される理由
必要に応じて、Google TV が特定の映画やテレビ番組をユーザーにおすすめする理由を構築するために使用できるおすすめの理由を指定します。
//Allows us to construct reason: "Because it is top 10 on your Channel"
val topOnPartner = RecommendationReasonTopOnPartner
.Builder()
.setNum(10) //any valid integer value
.build()
//Allows us to construct reason: "Because it is popular on your Channel"
val popularOnPartner = RecommendationReasonPopularOnPartner
.Builder()
.build()
//Allows us to construct reason: "New to your channel, or Just added"
val newOnPartner = RecommendationReasonNewOnPartner
.Builder()
.build()
//Allows us to construct reason: "Because you watched Star Wars"
val watchedSimilarTitles = RecommendationReasonWatchedSimilarTitles
.addSimilarWatchedTitleName("Movie or TV Show Title")
.addSimilarWatchedTitleName("Movie or TV Show Title")
.Builder()
.build()
//Allows us to construct reason: "Recommended for you by ChannelName"
val recommendedForUser = RecommendationReasonRecommendedForUser
.Builder()
.build()
val watchAgain = RecommendationReasonWatchAgain
.Builder()
.build()
val fromUserWatchList = RecommendationReasonFromUserWatchlist
.Builder()
.build()
val userLikedOnPartner = RecommendationReasonUserLikedOnPartner
.Builder()
.setTitleName("Movie or TV Show Title")
.build()
val generic = RecommendationReasonGeneric.Builder().build()
表示時間枠
エンティティを期間限定でのみ使用できるようにするには、カスタムの有効期限を設定します。明示的な有効期限が指定されていないエンティティは、60 日後に自動的に期限切れになり、消去されます。したがって、エンティティを早期に期限切れにする必要がある場合にのみ、有効期限を設定します。このような可用性ウィンドウを複数指定します。
val window1 = DisplayTimeWindow
.Builder()
.setStartTimeStampMillis(now()+ 1.days.toMillis())
.setEndTimeStampMillis(now()+ 30.days.toMillis())
val window2 = DisplayTimeWindow
.Builder()
.setEndTimeStampMillis(now()+ 30.days.toMillis())
val availabilityTimeWindows: List<DisplayTimeWindow> = listof(window1,window2)
DataFeedElementId
メディア カタログまたはメディア アクション フィードを Google TV と統合している場合は、映画やテレビ番組用に個別のエンティティを作成する必要はありません。代わりに、必要なフィールド DataFeedElementId を含む MediaActionFeed エンティティを作成できます。この ID は一意で、取り込まれたフィード コンテンツの識別とメディア コンテンツの検索に役立つため、メディア アクション フィードの ID と一致している必要があります。
val id = "dataFeedEleemntId"
MovieEntity
必須フィールドをすべて含む MovieEntity
を作成する例を次に示します。
val movieEntity = MovieEntity.Builder()
.setName("Movie name")
.setDescription("A sentence describing movie.")
.addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
.addPosterImages(images)
// Suppose the duration is 2 hours, it is 72000000 in milliseconds
.setDurationMills(72000000)
.build()
ジャンル、コンテンツの評価、リリース日、おすすめの理由、公開期間などの追加データを指定できます。これらのデータは、Google TV で表示の強化やフィルタリングに使用される場合があります。
val genres = Arrays.asList("Action", "Science fiction");
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("pg-13").build();
val contentRatings = Arrays.asList(rating1);
//Suppose release date is 11-02-2025
val releaseDate = 1739233800000L
val movieEntity = MovieEntity.Builder()
...
.addGenres(genres)
.setReleaseDateEpochMillis(releaseDate)
.addContentRatings(contentRatings)
.setRecommendationReason(topOnPartner or watchedSimilarTitles)
.addAllAvailabilityTimeWindows(availabilityTimeWindows)
.build()
TvShowEntity
必須フィールドをすべて含む TvShowEntity
を作成する例を次に示します。
val tvShowEntity = TvShowEntity.Builder()
.setName("Show title")
.setDescription("A sentence describing TV Show.")
.addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
.addPosterImages(images)
.build();
必要に応じて、ジャンル、コンテンツの評価、おすすめの理由、オファーの価格、シーズン数、視聴可能時間帯などの追加データを指定します。これらのデータは、Google TV で表示の強化やフィルタリングに使用される場合があります。
val genres = Arrays.asList("Action", "Science fiction");
val rating1 = RatingSystem.Builder()
.setAgencyName("MPAA")
.setRating("pg-13")
.build();
val price = Price.Builder()
.setCurrentPrice("$14.99")
.setStrikethroughPrice("$16.99")
.build();
val contentRatings = Arrays.asList(rating1);
val seasonCount = 5;
val tvShowEntity = TvShowEntity.Builder()
...
.addGenres(genres)
.addContentRatings(contentRatings)
.setRecommendationReason(topOnPartner or watchedSimilarTitles)
.addAllAvailabilityTimeWindows(availabilityTimeWindows)
.setSeasonCount(seasonCount)
.setPrice(price)
.build()
MediaActionFeedEntity
必須フィールドをすべて含む MediaActionFeedEntity
を作成する例を次に示します。
val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
.setDataFeedElementId(id)
.build()
必要に応じて、説明、おすすめの理由、表示時間帯などの追加データを指定します。これらのデータは、Google TV が高度な表示やフィルタリングの目的で使用します。
val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
.setName("Movie name or TV Show name")
.setDescription("A sentence describing an entity")
.setRecommendationReason(topOnPartner or watchedSimilarTitles)
.addPosterImages(images)
.build()
これらの手順を実装することで、デベロッパーは動画コンテンツのレコメンデーションを Google TV に適切に統合し、ユーザーの見つけやすさとエンゲージメントを高め、すべてのデバイスでユーザーに一貫したパーソナライズされた視聴体験を提供できます。