Ten przewodnik zawiera instrukcje dla deweloperów dotyczące integracji rekomendowanych treści wideo za pomocą pakietu Engage SDK, aby wypełniać rekomendacjami różne usługi Google, takie jak telewizory, telefony komórkowe i tablety.
Rekomendacje wykorzystują grupę rekomendacji, aby wyświetlać filmy i seriale z różnych aplikacji w jednym układzie interfejsu. Każdy partner deweloper może transmitować maksymalnie 25 elementów w każdym klastrze rekomendacji, a w jednym żądaniu może być maksymalnie 7 klastrów rekomendacji.
Przygotowanie
Zanim zaczniesz, wykonaj te czynności. 1. Sprawdź, czy aplikacja jest kierowana na interfejs API na poziomie 19 lub wyższym.
Dodaj bibliotekę
com.google.android.engagedo aplikacji.Do integracji możesz użyć oddzielnych pakietów SDK: jednego do aplikacji mobilnych i jednego do aplikacji na telewizory.
Na urządzenia mobilne
dependencies { implementation 'com.google.android.engage:engage-core:1.5.9 }do telewizora
dependencies { implementation 'com.google.android.engage:engage-tv:1.0.5 }W pliku
AndroidManifest.xmlustaw środowisko usługi Engage na produkcyjne.W przypadku pakietu APK na urządzenia mobilne
<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>Wykonaj publikowanie w usłudze na pierwszym planie.
Dane rekomendacji publikuj maksymalnie raz dziennie, w odpowiedzi na jedno z tych zdarzeń:
- Pierwsze logowanie użytkownika w danym dniu. (lub)
- Gdy użytkownik zacznie korzystać z aplikacji.
Integracja
AppEngagePublishClient publikuje klaster rekomendacji. Użyj metody publishRecommendationClusters, aby opublikować obiekt rekomendacji.
Użyj isServiceAvailable()2, aby sprawdzić, czy usługa jest dostępna do integracji.
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.
}
}
Klastry rekomendacji i żądanie publikacji
Klastry to logiczne grupy encji. Poniższe przykłady kodu wyjaśniają, jak tworzyć klastry zgodnie z własnymi preferencjami i jak tworzyć żądanie publikowania dla wszystkich klastrów.
// 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()
Tworzenie profilu konta
Aby umożliwić personalizację Google TV, podaj informacje o koncie i profilu. Użyj AccountProfile, aby podać:
- Identyfikator konta: unikalny identyfikator konta użytkownika w Twojej aplikacji. Może to być rzeczywisty identyfikator konta lub odpowiednio zamaskowana wersja.
- Identyfikator profilu (opcjonalny): jeśli Twoja aplikacja obsługuje wiele profili na jednym koncie, podaj unikalny identyfikator konkretnego profilu użytkownika.
- Locale(opcjonalnie): możesz opcjonalnie podać preferowany język użytkownika.
To pole jest przydatne, jeśli wysyłasz
MediaActionFeedEntitywRecommendationRequest.
// 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();
Gdy usługa otrzyma żądanie, w ramach jednej transakcji zostaną wykonane te działania:
- Istniejące dane
RecommendationsClusterod dewelopera zostaną usunięte. - Dane z żądania są analizowane i zapisywane w zaktualizowanym
RecommendationsCluster. W przypadku błędu całe żądanie jest odrzucane, a dotychczasowy stan jest zachowywany.
Synchronizacja na różnych urządzeniach
Flaga SyncAcrossDevices określa, czy dane klastra rekomendacji użytkownika są udostępniane w Google TV i dostępne na jego urządzeniach, takich jak telewizor, telefon czy tablet. Aby rekomendacja działała, musi mieć wartość „true”.
Uzyskiwanie zgody
Aplikacja multimedialna musi zawierać wyraźne ustawienie umożliwiające włączenie lub wyłączenie synchronizacji na różnych urządzeniach. Wyjaśnij użytkownikowi korzyści i zapisz jego preferencje, a następnie zastosuj je w publishRecommendations Request. Aby w pełni wykorzystać funkcję obejmującą wiele urządzeń, sprawdź, czy aplikacja uzyskuje zgodę użytkownika i umożliwia SyncAcrossDevices na true.
Usuwanie danych dotyczących odkrywania filmów
Aby ręcznie usunąć dane użytkownika z serwera Google TV przed upływem standardowego 60-dniowego okresu przechowywania, użyj metody client.deleteClusters(). Po otrzymaniu prośby usługa usuwa wszystkie dotychczasowe dane dotyczące odkrywania filmów z profilu konta lub z całego konta.
Wyliczenie DeleteReason określa przyczynę usunięcia danych.
Poniższy kod usuwa rekomendacje po wylogowaniu.
// 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()
)
Tworzenie encji
Pakiet SDK ma zdefiniowane różne elementy reprezentujące każdy typ produktu. W przypadku klastra rekomendacji obsługiwane są te elementy:
MediaActionFeedEntityMovieEntityTvShowEntityLiveTvChannelEntityLiveTvProgramEntity
Opis
Podaj krótki opis każdej jednostki. Będzie on wyświetlany, gdy użytkownicy najedzie na nią kursorem, co pozwoli im uzyskać dodatkowe informacje.
Identyfikatory URI odtwarzania specyficzne dla platformy
Utwórz identyfikatory URI odtwarzania dla każdej obsługiwanej platformy: Android TV, Android lub iOS. Dzięki temu system może wybrać odpowiedni identyfikator URI do odtwarzania filmu na danej platformie.
W rzadkich przypadkach, gdy identyfikatory URI odtwarzania są identyczne na wszystkich platformach, powtórz tę czynność dla każdej platformy.
// 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()
Obrazy plakatu
Obrazy plakatu wymagają identyfikatora URI i wymiarów w pikselach (wysokości i szerokości). Aby kierować reklamy na różne urządzenia, prześlij wiele obrazów plakatu, ale sprawdź, czy wszystkie obrazy mają współczynnik proporcji 16:9 i minimalną wysokość 200 pikseli, aby zapewnić prawidłowe wyświetlanie jednostki „Rekomendacje”, zwłaszcza w Entertainment Space Google. Obrazy o wysokości mniejszej niż 200 pikseli mogą się nie wyświetlać.
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)
Powód rekomendacji
Opcjonalnie podaj powód rekomendacji, który może być używany przez Google TV do tworzenia uzasadnień, dlaczego zaproponować użytkownikowi konkretny film lub program telewizyjny.
//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()
Wyświetlanie przedziału czasu
Jeśli encja ma być dostępna tylko przez ograniczony czas, ustaw niestandardowy czas wygaśnięcia. Jeśli nie określisz czasu wygaśnięcia, encje automatycznie wygasną i zostaną usunięte po 60 dniach. Dlatego ustawiaj czas wygaśnięcia tylko wtedy, gdy encje mają wygasnąć wcześniej. Możesz określić kilka takich przedziałów dostępności.
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
Jeśli masz zintegrowany katalog multimediów lub plik danych działań związanych z multimediami z Google TV, nie musisz tworzyć osobnych elementów dla filmów ani programów telewizyjnych. Zamiast tego możesz utworzyć element MediaActionFeed, który zawiera wymagane pole DataFeedElementId. Ten identyfikator musi być unikalny i zgodny z identyfikatorem w pliku danych z działaniami dotyczącymi multimediów, ponieważ pomaga identyfikować przetworzone treści z pliku danych i wyszukiwać treści multimedialne.
val id = "dataFeedEleemntId"
MovieEntity
Oto przykład tworzenia obiektu MovieEntity ze wszystkimi wymaganymi polami:
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()
Możesz podać dodatkowe dane, takie jak gatunki, oceny treści, data premiery, powód rekomendacji i okresy dostępności, które mogą być wykorzystywane przez Google TV do ulepszonego wyświetlania lub filtrowania.
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
Oto przykład tworzenia obiektu TvShowEntity ze wszystkimi wymaganymi polami:
val tvShowEntity = TvShowEntity.Builder()
.setName("Show title")
.setDescription("A sentence describing TV Show.")
.addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
.addPosterImages(images)
.build();
Opcjonalnie możesz podać dodatkowe dane, takie jak gatunki, oceny treści, powód rekomendacji, cena oferty, liczba sezonów lub przedział czasowy dostępności, które mogą być wykorzystywane przez Google TV do wyświetlania ulepszonych treści lub filtrowania.
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
Oto przykład tworzenia obiektu MediaActionFeedEntity ze wszystkimi wymaganymi polami:
val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
.setDataFeedElementId(id)
.build()
Opcjonalnie możesz podać dodatkowe dane, takie jak opis, powód rekomendacji i okres wyświetlania, które mogą być wykorzystywane przez Google TV do ulepszania wyświetlania lub filtrowania.
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
Reprezentuje kanał telewizyjny nadawany na żywo. Oto przykład tworzenia elementu LiveTvChannelEntity ze wszystkimi wymaganymi polami:
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()
Opcjonalnie możesz podać dodatkowe dane, takie jak oceny treści lub powód rekomendacji.
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
Jest to karta programu telewizyjnego na żywo, który jest emitowany lub ma być emitowany na kanale telewizyjnym na żywo. Oto przykład tworzenia LiveTvProgramEntity ze wszystkimi wymaganymi polami:
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()
Opcjonalnie możesz podać dodatkowe dane, takie jak oceny treści, gatunki czy powód rekomendacji.
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()
Wykonując te czynności, deweloperzy mogą skutecznie zintegrować rekomendacje treści wideo z Google TV, zwiększając wykrywalność i zaangażowanie użytkowników oraz zapewniając im spójne i spersonalizowane wrażenia podczas oglądania na wszystkich urządzeniach.