Panduan ini berisi petunjuk bagi developer untuk mengintegrasikan konten video yang direkomendasikan, menggunakan Engage SDK, untuk mengisi pengalaman rekomendasi di seluruh platform Google, seperti TV, perangkat seluler, dan tablet.
Rekomendasi memanfaatkan Cluster rekomendasi untuk menampilkan film dan acara TV dari beberapa aplikasi dalam satu pengelompokan UI. Setiap partner developer dapat menyiarkan maksimum 25 entity di setiap cluster rekomendasi dan maksimum ada 7 cluster rekomendasi per permintaan.
Persiapan
Sebelum memulai, selesaikan langkah-langkah berikut. 1. Pastikan aplikasi Anda menargetkan API level 19 atau yang lebih tinggi untuk integrasi ini.
Tambahkan library
com.google.android.engageke aplikasi Anda.Ada SDK terpisah untuk digunakan dalam integrasi: satu untuk aplikasi seluler dan satu untuk aplikasi TV.
Untuk Perangkat Seluler
dependencies { implementation 'com.google.android.engage:engage-core:1.5.9 }untuk TV
dependencies { implementation 'com.google.android.engage:engage-tv:1.0.5 }Setel lingkungan layanan Engage ke produksi dalam file
AndroidManifest.xml.Untuk APK seluler
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>Untuk APK TV
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>Menjalankan publikasi di layanan latar depan.
Publikasikan data Rekomendasi paling banyak sekali sehari, dipicu oleh salah satu dari
- Login pertama pengguna pada hari itu. (atau)
- Saat pengguna mulai berinteraksi dengan aplikasi.
Integrasi
AppEngagePublishClient memublikasikan cluster rekomendasi. Gunakan metode publishRecommendationClusters untuk memublikasikan objek rekomendasi.
Gunakan isServiceAvailable()2 untuk memeriksa apakah layanan tersedia untuk
integrasi.
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 rekomendasi dan permintaan publikasi
Cluster adalah pengelompokan logis entitas. Contoh kode berikut menjelaskan cara membuat cluster berdasarkan preferensi Anda dan cara membuat permintaan publikasi untuk semua cluster.
// cluster for popular movies
val recommendationCluster1 = RecommendationCluster
.Builder()
.addEntity(movie1)
.addEntity(movie2)
.addEntity(movie3)
.addEntity(movie4)
.addEntity(tvShow)
// This cluster is meant to be used as an individual provider row
.setRecommendationClusterType(TYPE_PROVIDER_ROW)
.setTitle("Popular Movies")
.build()
// cluster for live TV programs
val recommendationCluster2 = RecommendationCluster
.Builder()
.addEntity(liveTvProgramEntity1)
.addEntity(liveTvProgramEntity2)
.addEntity(liveTvProgramEntity3)
.addEntity(liveTvProgramEntity4)
.addEntity(liveTvProgramEntity5)
// This cluster is meant to be used as an individual provider row
.setRecommendationClusterType(TYPE_PROVIDER_ROW)
.setTitle("Popular Live TV Programs")
.build()
// creating a publishing request
val recommendationRequest = PublishRecommendationClustersRequest
.Builder()
.setSyncAcrossDevices(true)
.setAccountProfile(accountProfile)
.addRecommendationCluster(recommendationCluster1)
.addRecommendationCluster(recommendationCluster2)
.build()
Membuat profil akun
Untuk mengizinkan pengalaman yang dipersonalisasi di Google TV, berikan informasi akun dan profil. Gunakan AccountProfile untuk memberikan:
- ID Akun: ID unik yang merepresentasikan akun pengguna dalam aplikasi Anda. ID ini dapat berupa ID akun yang sebenarnya atau versi yang di-obfuscate dengan tepat.
- ID Profil (opsional): Jika aplikasi Anda mendukung beberapa profil dalam satu akun, berikan ID unik untuk profil pengguna tertentu.
- Lokalitas(opsional): Anda dapat memberikan bahasa pilihan pengguna secara opsional.
Kolom ini berguna jika Anda mengirim
MediaActionFeedEntitydiRecommendationRequest.
// 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();
Saat layanan menerima permintaan tersebut, tindakan berikut akan terjadi dalam satu transaksi:
- Data
RecommendationsClusteryang ada dari partner developer akan dihapus. - Data dari permintaan akan diuraikan dan disimpan di
RecommendationsClusteryang diperbarui. Jika terjadi error, seluruh permintaan akan ditolak dan status yang ada dipertahankan.
Sinkronisasi lintas perangkat
Flag SyncAcrossDevices mengontrol apakah data pengelompokan rekomendasi pengguna dibagikan ke Google TV dan tersedia di seluruh perangkatnya seperti TV, ponsel, tablet. Agar rekomendasi berfungsi, setel ke benar (true).
Mendapatkan izin
Aplikasi media harus menyediakan setelan yang jelas untuk mengaktifkan atau menonaktifkan sinkronisasi lintas perangkat. Jelaskan manfaatnya kepada pengguna dan simpan preferensi pengguna
sekali saja, lalu terapkan di publishRecommendations Request yang sesuai. Untuk
mengoptimalkan fitur lintas perangkat, pastikan aplikasi mendapatkan izin pengguna
dan mengaktifkan SyncAcrossDevices ke true.
Menghapus data penemuan video
Untuk menghapus data pengguna secara manual dari server Google TV sebelum periode retensi 60 hari standar, gunakan metode client.deleteClusters(). Setelah
menerima permintaan, layanan akan menghapus semua data penemuan video yang ada untuk profil akun, atau untuk seluruh akun.
Enum DeleteReason menentukan alasan penghapusan data.
Kode berikut menghapus rekomendasi saat logout.
// 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()
)
Membuat entity
SDK telah menentukan entity yang berbeda untuk mewakili setiap jenis item. Entitas berikut didukung untuk cluster Rekomendasi:
MediaActionFeedEntityMovieEntityTvShowEntityLiveTvChannelEntityLiveTvProgramEntity
Deskripsi
Berikan deskripsi singkat untuk setiap entitas; deskripsi ini akan ditampilkan saat pengguna mengarahkan kursor ke entitas, sehingga memberikan detail tambahan.
URI pemutaran khusus platform
Buat URI pemutaran untuk setiap platform yang didukung: Android TV, Android, atau iOS. Hal ini memungkinkan sistem memilih URI yang sesuai untuk pemutaran video di masing-masing platform.
Dalam kasus yang jarang terjadi saat URI pemutaran identik untuk semua platform, ulangi untuk setiap platform.
// 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()
Gambar poster
Gambar poster memerlukan URI dan dimensi piksel (tinggi dan lebar). Menargetkan faktor bentuk yang berbeda dengan menyediakan beberapa gambar poster, tetapi pastikan semua gambar mempertahankan rasio aspek 16:9 dan tinggi minimum 200 piksel untuk tampilan yang benar dari entitas "Rekomendasi", terutama dalam Entertainment Space Google. Gambar dengan tinggi kurang dari 200 piksel mungkin tidak ditampilkan.
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)
Alasan rekomendasi
Secara opsional, berikan alasan rekomendasi yang dapat digunakan oleh Google TV untuk membuat alasan mengapa menyarankan Film atau Acara TV tertentu kepada pengguna.
//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()
Menampilkan periode waktu
Jika entitas hanya boleh tersedia untuk waktu terbatas, tetapkan waktu habis masa berlaku kustom. Tanpa waktu habis masa berlaku yang eksplisit, entitas akan otomatis habis masa berlakunya dan dihapus setelah 60 hari. Jadi, tetapkan waktu habis masa berlaku hanya jika entity perlu segera habis masa berlakunya. Tentukan beberapa periode ketersediaan tersebut.
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
Jika telah mengintegrasikan katalog Media atau feed Tindakan media dengan Google TV, Anda tidak perlu membuat entitas terpisah untuk Film atau Acara TV, tetapi Anda dapat membuat Entitas MediaActionFeed yang menyertakan kolom DataFeedElementId yang diperlukan. ID ini harus unik dan harus cocok dengan ID di Feed Tindakan Media karena membantu mengidentifikasi konten feed yang di-ingest dan melakukan pencarian konten media.
val id = "dataFeedEleemntId"
MovieEntity
Berikut adalah contoh pembuatan MovieEntity dengan semua kolom wajib diisi:
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()
Anda dapat memberikan data tambahan seperti genre, rating konten, tanggal rilis, alasan rekomendasi, dan periode waktu ketersediaan, yang dapat digunakan oleh Google TV untuk tujuan tampilan atau pemfilteran yang lebih baik.
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
Berikut adalah contoh pembuatan TvShowEntity dengan semua kolom wajib diisi:
val tvShowEntity = TvShowEntity.Builder()
.setName("Show title")
.setDescription("A sentence describing TV Show.")
.addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
.addPosterImages(images)
.build();
Secara opsional, berikan data tambahan seperti genre, rating konten, alasan rekomendasi, harga penawaran, jumlah season, atau jangka waktu ketersediaan, yang dapat digunakan oleh Google TV untuk tujuan tampilan atau pemfilteran yang lebih baik.
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
Berikut contoh pembuatan MediaActionFeedEntity dengan semua kolom wajib diisi:
val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
.setDataFeedElementId(id)
.build()
Secara opsional, berikan data tambahan seperti deskripsi, alasan rekomendasi, dan jangka waktu penayangan, yang dapat digunakan oleh Google TV untuk tujuan penyaringan atau tampilan yang lebih baik.
val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
.setName("Movie name or TV Show name")
.setDescription("A sentence describing an entity")
.setRecommendationReason(topOnPartner or watchedSimilarTitles)
.addPosterImages(images)
.build()
LiveTvChannelEntity
Ini mewakili channel TV live. Berikut contoh pembuatan
LiveTvChannelEntity dengan semua kolom wajib diisi:
val liveTvChannelEntity = LiveTvChannelEntity.Builder()
.setName("Channel Name")
// ID of the live TV channel
.setEntityId("https://www.example.com/channel/12345")
.setDescription("A sentence describing this live TV channel.")
// channel playback uri must contain at least PlatformType.TYPE_ANDROID_TV
.addPlatformSpecificPlaybackUri(channelPlaybackUris)
.addLogoImage(logoImage)
.build()
Secara opsional, berikan data tambahan seperti rating konten atau alasan rekomendasi.
val rating1 = RatingSystem.Builder()
.setAgencyName("MPAA")
.setRating("pg-13")
.build()
val contentRatings = Arrays.asList(rating1)
val liveTvChannelEntity = LiveTvChannelEntity.Builder()
...
.addContentRatings(contentRatings)
.setRecommendationReason(topOnPartner)
.build()
LiveTvProgramEntity
Ini menampilkan kartu program TV live yang sedang atau dijadwalkan untuk ditayangkan di
saluran TV live. Berikut contoh pembuatan LiveTvProgramEntity
dengan semua kolom wajib diisi:
val liveTvProgramEntity = LiveTvProgramEntity.Builder()
// First set the channel information
.setChannelName("Channel Name")
.setChanelId("https://www.example.com/channel/12345")
// channel playback uri must contain at least PlatformType.TYPE_ANDROID_TV
.addPlatformSpecificPlaybackUri(channelPlaybackUris)
.setChannelLogoImage(channelLogoImage)
// Then set the program or card specific information.
.setName("Program Name")
.setEntityId("https://www.example.com/schedule/123")
.setDescription("Program Desccription")
.addAvailabilityTimeWindow(
DisplayTimeWindow.Builder()
.setStartTimestampMillis(1756713600000L)// 2025-09-01T07:30:00+0000
.setEndTimestampMillis(1756715400000L))// 2025-09-01T08:00:00+0000
.addPosterImage(programImage)
.build()
Secara opsional, berikan data tambahan seperti rating konten, genre, atau alasan rekomendasi.
val rating1 = RatingSystem.Builder()
.setAgencyName("MPAA")
.setRating("pg-13")
.build()
val contentRatings = Arrays.asList(rating1)
val genres = Arrays.asList("Action", "Science fiction")
val liveTvProgramEntity = LiveTvProgramEntity.Builder()
...
.addContentRatings(contentRatings)
.addGenres(genres)
.setRecommendationReason(topOnPartner)
.build()
Dengan menerapkan langkah-langkah ini, developer dapat berhasil mengintegrasikan rekomendasi konten video ke Google TV, meningkatkan penemuan dan engagement pengguna, serta memberikan pengalaman menonton yang konsisten dan dipersonalisasi bagi pengguna di semua perangkat mereka.