本指南適用對象為開發人員,提供使用 Engage SDK 整合推薦影片內容的操作說明,以便在 Google 途徑 (例如電視、行動裝置和平板電腦) 中填入推薦內容體驗。
推薦功能會利用推薦叢集,在單一 UI 群組中顯示多個應用程式提供的電影和電視節目。每個開發合作夥伴最多可在每個推薦叢集中播送 25 個實體,且每個要求最多可包含 7 個推薦叢集。
事前作業
在開始之前,請先完成下列步驟。1. 確認應用程式指定的 API 級別為 19 以上,才能進行此整合。
將
com.google.android.engage
程式庫新增至應用程式。整合時需要使用不同的 SDK:一個用於行動應用程式,另一個用於電視應用程式。
行動裝置適用
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>
適用於電視的 APK
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
在前景服務上執行發布作業。
最多每天發布一次推薦內容資料,並由下列任一項目觸發:
- 使用者當天首次登入。(或)
- 使用者開始與應用程式互動時。
整合
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 或經過適當模糊處理的版本。
- 設定檔 ID (選用):如果應用程式支援單一帳戶中的多個設定檔,請為特定使用者設定檔提供專屬 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();
服務收到要求後,系統會在單一交易中執行以下動作:
- 移除開發合作夥伴提供的現有
RecommendationsCluster
資料。 - 剖析要求所提供的資料並儲存在更新後的
RecommendationsCluster
中。如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。
跨裝置同步
SyncAcrossDevices
標記可控管是否要將使用者的推薦叢集資料分享給 Google TV,並在電視、手機和平板電腦等裝置上提供。為了讓建議生效,您必須將其設為 true。
取得同意聲明
媒體應用程式必須提供明確的設定,可啟用或停用跨裝置同步處理。向使用者說明優點,並儲存使用者的偏好設定,然後在 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
為每個支援的平台建立播放 URI:Android TV、Android 或 iOS。這樣一來,系統就能在各個平台上選取適當的 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 和像素尺寸 (高度和寬度)。提供多張海報圖片,以便鎖定不同板型規格,但請確認所有圖片都維持 16:9 的顯示比例,且高度至少為 200 像素,以便正確顯示「Recommendations」實體,尤其是在 Google 的 Entertainment Space 中。高度小於 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,就不需要為電影或電視節目建立個別實體,而是可以建立 MediaActionFeed 實體,其中包含必要的 DataFeedElementId 欄位。這個 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,提升使用者的探索和參與度,並在所有裝置上為使用者提供一致且個人化的觀看體驗。