Engage SDK Watch: Instrukcje dotyczące integracji technicznej z usługami innych firm

Google tworzy platformę na urządzeniu, która porządkuje aplikacje użytkowników według kategorii i zapewnia nowe, atrakcyjne możliwości związane z oglądaniem i odkrywaniem treści aplikacji w spersonalizowany sposób. Dzięki temu partnerzy mogą prezentować swoje najlepsze treści na specjalnym kanale poza aplikacją.

Ten przewodnik zawiera instrukcje dla deweloperów, którzy chcą zintegrować swoje treści wideo, korzystając z pakietu SDK dla Agencji do zapełnienia zarówno tej nowej powierzchni, jak i dotychczasowych platform Google.

Szczegóły integracji

Terminologia

Ta integracja obejmuje 3 typy klastrów: Rekomendacja, Kontynuacja i Polecane.

  • Klastry rekomendacji wyświetlają spersonalizowane sugestie dotyczące treści od konkretnego partnera ds. deweloperów.

    Rekomendacje mają taką strukturę:

    • Klaster rekomendacji: widok interfejsu zawierający grupę rekomendacji od tego samego partnera ds. deweloperów.

      Rysunek 1. Interfejs Entertainment Space z klastrem rekomendacji od jednego partnera.
    • Encja: obiekt reprezentujący pojedynczy element w klastrze. Elementem może być np. film, program telewizyjny, serial telewizyjny lub wideo na żywo. Listę obsługiwanych typów encji znajdziesz w sekcji Podaj dane encji.

      Rysunek 2. Interfejs Entertainment Space z pojedynczym elementem w klastrze rekomendacji pojedynczego partnera.
  • Klaster Kontynuacja pokazuje niedokończone filmy i odpowiednie nowo opublikowane odcinki wielu partnerów deweloperów w jednej grupie UI. Każdy deweloper będzie mógł transmitować maksymalnie 10 encji w klastrze kontynuacji. Badania pokazują, że największe zaangażowanie użytkowników największe są spersonalizowane rekomendacje i treści z sekcji Kontynuuj.

    Rysunek 3. Interfejs Entertainment Space z grupą kontynuacji z niedokończonymi rekomendacjami od wielu partnerów (w tej chwili widoczna jest tylko jedna rekomendacja).
  • Klaster Polecane prezentuje wybrane elementy od wielu partnerów deweloperów w jednym grupowaniu UI. U góry interfejsu będzie widoczny pojedynczy klaster Polecane, miejsce docelowe nadrzędne względem wszystkich klastrów rekomendacji. Każdy partner deweloper będzie mógł rozpowszechniać w klastrze Polecane maksymalnie 10 encji.

    Rysunek 4. Interfejs Entertainment Space z widocznym klastrem Polecane z rekomendacjami od wielu partnerów (w tej chwili widoczna jest tylko jedna rekomendacja).

Przygotowanie

Minimalny poziom interfejsu API: 19

Dodaj bibliotekę com.google.android.engage:engage-core do aplikacji:

dependencies {
    // Make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.engage:engage-core:1.4.0'
}

Więcej informacji znajdziesz w artykule o widoczności pakietów w Androidzie 11.

Podsumowanie

Projekt opiera się na implementacji powiązanej usługi.

Dane, które klient może publikować, podlegają tym ograniczeniom w przypadku różnych typów klastrów:

Typ klastra Limity klastrów Maksymalne limity encji w klastrze
Klastry rekomendacji Maksymalnie 5 Maksymalnie 50
Klaster kontynuacji Maksymalnie 1 Maksymalnie 10
Polecany klaster Maksymalnie 1 Maksymalnie 10

Krok 0. Migracja z dotychczasowej integracji pakietu SDK Media Home

Zmapuj modele danych z istniejącej integracji

Jeśli przechodzisz z dotychczasowej integracji Media Home, w tabeli poniżej znajdziesz informacje o mapowaniu modeli danych z dotychczasowych pakietów SDK na nowy pakiet Engage SDK:

Odpowiednik integracji MediaHomeVideoContract Odpowiednik integracji Google Workspace z pakietem SDK
com.google.android.mediahome.video.PreviewChannel com.google.android.engage.common.datamodel.RecommendationCluster
com.google.android.mediahome.video.PreviewChannel.Builder com.google.android.engage.common.datamodel.RecommendationCluster.Builder
com.google.android.mediahome.video.PreviewChannelHelper com.google.android.engage.video.service.AppEngageVideoClient
com.google.android.mediahome.video.PreviewProgram Podzielony na osobne klasy: EventVideo, LiveStreamingVideo, Movie, TvEpisode, TvSeason, TvShow, VideoClipEntity
com.google.android.mediahome.video.PreviewProgram.Builder Są podzielone na kreatory w oddzielnych klasach: EventVideo, LiveStreamingVideo, Movie, TvEpisode, TvSeason, TvShow, VideoClipEntity
com.google.android.mediahome.video.VideoContract Już nie potrzebuję tej usługi.
com.google.android.mediahome.video.WatchNextProgram Podzielony na atrybuty w osobnych klasach: EventVideoEntity, LiveStreamingVideoEntity, MovieEntity, TvEpisodeEntity, TvSeasonEntity, TvShowEntity, VideoClipEntity
com.google.android.mediahome.video.WatchNextProgram.Builder Podzielony na atrybuty w osobnych klasach: EventVideoEntity, LiveStreamingVideoEntity, MovieEntity, TvEpisodeEntity, TvSeasonEntity, TvShowEntity, VideoClipEntity

Publikowanie klastrów w pakiecie Media Home SDK a pakiet SDK dla Agencji

Za pomocą pakietu Media Home SDK klastry i elementy były publikowane przy użyciu osobnych interfejsów API:

// 1. Fetch existing channels
List<PreviewChannel> channels = PreviewChannelHelper.getAllChannels();

// 2. If there are no channels, publish new channels
long channelId = PreviewChannelHelper.publishChannel(builder.build());

// 3. If there are existing channels, decide whether to update channel contents
PreviewChannelHelper.updatePreviewChannel(channelId, builder.build());

// 4. Delete all programs in the channel
PreviewChannelHelper.deleteAllPreviewProgramsByChannelId(channelId);

// 5. publish new programs in the channel
PreviewChannelHelper.publishPreviewProgram(builder.build());

Dzięki pakietowi SDK dla Agencji publikowanie klastrów i encji jest łączone w jedno wywołanie interfejsu API. Wszystkie encje należące do klastra są publikowane razem z tym klastrem:

Kotlin


RecommendationCluster.Builder()
            .addEntity(MOVIE_ENTITY)
            .addEntity(MOVIE_ENTITY)
            .addEntity(MOVIE_ENTITY)
            .setTitle("Top Picks For You")
            .build()

Java


new RecommendationCluster.Builder()
                        .addEntity(MOVIE_ENTITY)
                        .addEntity(MOVIE_ENTITY)
                        .addEntity(MOVIE_ENTITY)
                        .setTitle("Top Picks For You")
                        .build();

Krok 1. Podaj dane encji

Pakiet SDK ma zdefiniowane różne elementy reprezentujące każdy typ elementu. W przypadku kategorii Zegarki obsługujemy:

  1. MovieEntity
  2. TvShowEntity
  3. TvSeasonEntity
  4. TvEpisodeEntity
  5. LiveStreamingVideoEntity
  6. VideoClipEntity

W tabeli poniżej opisujemy atrybuty i wymagania dla poszczególnych typów.

MovieEntity

Atrybut Wymóg Uwagi
Nazwa Wymagany
Obrazy plakatu Wymagany Wymagany jest co najmniej 1 obraz o współczynniku proporcji. (Preferowana jest orientacja pozioma, ale w zależności od sytuacji zalecamy przesyłanie zarówno obrazów pionowych, jak i poziomych).

Wskazówki znajdziesz w specyfikacji obrazów.

Identyfikator URI odtwarzania Wymagany

Precyzyjny link do aplikacji dostawcy, aby rozpocząć odtwarzanie filmu.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Identyfikator URI strony z informacjami Opcjonalnie

Precyzyjny link do aplikacji dostawcy, który pozwala wyświetlić szczegółowe informacje o filmie.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Data premiery Wymagany W milisekundach w epoce.
Dostępność Wymagany

AVAILABLE: treść jest dostępna dla użytkownika bez wykonywania dalszych czynności.

FREE_WITH_SUBSCRIPTION: treści są dostępne po wykupieniu subskrypcji przez użytkownika.

PAID_CONTENT: treści wymagają zakupu lub wypożyczenia przez użytkownika.

KUPIONE: treść została kupiona lub wypożyczona przez użytkownika.

Cena oferty Opcjonalnie Dowolny tekst
Czas działania Wymagany W milisekundach.
Gatunek Wymagany Dowolny tekst
Oceny treści Wymagany Tekst dowolny, zgodny ze standardem branżowym. (Przykład)
Typ „Warte obejrzenia” Wymagane warunkowo

Musisz podać go, gdy element znajduje się w klastrze kontynuacji i musi być jednym z tych 4 typów:

KONTYNUUJ: użytkownik obejrzał już ponad 1 minutę tych treści.

NOWOŚĆ: użytkownik obejrzał wszystkie dostępne odcinki niektórych odcinków, ale pojawił się nowy odcinek i jest tylko jeden nieobejrzany odcinek. Dotyczy to m.in. programów telewizyjnych, nagranych meczów piłki nożnej w jednym serialu.

DALEJ: użytkownik obejrzał co najmniej 1 pełny odcinek niektórych treści w postaci odcinków, ale pozostał dokładnie 1 odcinek lub pozostał dokładnie 1 odcinek, w którym ostatni odcinek nie jest „NOWY”. Został on opublikowany, zanim użytkownik zaczął oglądać treści w formie odcinków.

LISTA DO obejrzenia: użytkownik jednoznacznie chce dodać film, wydarzenie lub serial do listy Do obejrzenia, aby ręcznie wybrać, co chce obejrzeć w następnej kolejności.

Czas ostatniego zaangażowania Wymagane warunkowo Należy je podać, gdy element znajduje się w klastrze kontynuacji. W milisekundach epoki.
Czas ostatniej pozycji odtwarzania Wymagane warunkowo Należy podać je, gdy element znajduje się w klastrze kontynuacyjnym, a element WatchNextType ma wartość Continue. W milisekundach w epoce.

TvShowEntity

Atrybut Wymóg Uwagi
Nazwa Wymagany
Obrazy plakatu Wymagany Wymagany jest co najmniej 1 obraz o współczynniku proporcji. (Preferowana jest orientacja pozioma, ale w zależności od sytuacji zalecamy przesyłanie zarówno obrazów pionowych, jak i poziomych).

Wskazówki znajdziesz w specyfikacji obrazów.

Identyfikator URI strony z informacjami Wymagany

Precyzyjny link do aplikacji dostawcy, który pozwala wyświetlić szczegóły programu telewizyjnego.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Identyfikator URI odtwarzania Opcjonalnie

Precyzyjny link do aplikacji dostawcy, aby rozpocząć odtwarzanie programu telewizyjnego.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Data emisji pierwszego odcinka Wymagany W milisekundach w epoce.
Data najnowszego odcinka Opcjonalnie W milisekundach w epoce.
Dostępność Wymagany

AVAILABLE: treść jest dostępna dla użytkownika bez wykonywania dalszych czynności.

FREE_WITH_SUBSCRIPTION: treści są dostępne po wykupieniu subskrypcji przez użytkownika.

PAID_CONTENT: treści wymagają zakupu lub wypożyczenia przez użytkownika.

KUPIONE: treść została kupiona lub wypożyczona przez użytkownika.

Cena oferty Opcjonalnie Dowolny tekst
Liczba sezonów Wymagany Dodatnia liczba całkowita
Gatunek Wymagany Dowolny tekst
Oceny treści Wymagany Tekst dowolny, zgodny ze standardem branżowym. (Przykład)
Typ „Warte obejrzenia” Wymagane warunkowo

Musisz podać go, gdy element znajduje się w klastrze kontynuacji i musi być jednym z tych 4 typów:

KONTYNUUJ: użytkownik obejrzał już ponad 1 minutę tych treści.

NOWOŚĆ: użytkownik obejrzał wszystkie dostępne odcinki niektórych odcinków, ale pojawił się nowy odcinek i jest tylko jeden nieobejrzany odcinek. Dotyczy to m.in. programów telewizyjnych, nagranych meczów piłki nożnej w jednym serialu.

DALEJ: użytkownik obejrzał co najmniej 1 pełny odcinek niektórych treści w postaci odcinków, ale pozostał dokładnie 1 odcinek lub pozostał dokładnie 1 odcinek, w którym ostatni odcinek nie jest „NOWY”. Został on opublikowany, zanim użytkownik zaczął oglądać treści w formie odcinków.

LISTA DO obejrzenia: użytkownik jednoznacznie chce dodać film, wydarzenie lub serial do listy Do obejrzenia, aby ręcznie wybrać, co chce obejrzeć w następnej kolejności.

Czas ostatniego zaangażowania Wymagane warunkowo Należy je podać, gdy element znajduje się w klastrze kontynuacji. W milisekundach epoki.
Czas ostatniej pozycji odtwarzania Wymagane warunkowo Należy podać je, gdy element znajduje się w klastrze kontynuacyjnym, a element WatchNextType ma wartość Continue. W milisekundach w epoce.

TvSeasonEntity

Atrybut Wymóg Uwagi
Nazwa Wymagany
Obrazy plakatu Wymagany Wymagany jest co najmniej 1 obraz o współczynniku proporcji. (Preferowana jest orientacja pozioma, ale w zależności od sytuacji zalecamy przesyłanie zarówno obrazów pionowych, jak i poziomych).

Wskazówki znajdziesz w specyfikacji obrazów.

Identyfikator URI strony z informacjami Wymagany

Precyzyjny link do aplikacji dostawcy umożliwiającej wyświetlenie szczegółów sezonu programu telewizyjnego.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Identyfikator URI odtwarzania Opcjonalnie

Precyzyjny link do aplikacji dostawcy umożliwiającej rozpoczęcie oglądania sezonu programu telewizyjnego.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Wyświetl numer sezonu

Opcjonalny

Dostępne w wersji 1.3.1

Ciąg znaków
Data emisji pierwszego odcinka Wymagany W milisekundach w epoce.
Data najnowszego odcinka Opcjonalnie W milisekundach w epoce.
Dostępność Wymagany

AVAILABLE: treść jest dostępna dla użytkownika bez wykonywania dalszych czynności.

FREE_WITH_SUBSCRIPTION: treści są dostępne po wykupieniu subskrypcji przez użytkownika.

PAID_CONTENT: treści wymagają zakupu lub wypożyczenia przez użytkownika.

KUPIONE: treść została kupiona lub wypożyczona przez użytkownika.

Cena oferty Opcjonalnie Dowolny tekst
Liczba odcinków Wymagany Dodatnia liczba całkowita
Gatunek Wymagany Dowolny tekst
Oceny treści Wymagany Tekst dowolny, zgodny ze standardem branżowym. (Przykład)
Typ „Warte obejrzenia” Wymagane warunkowo

Musisz podać go, gdy element znajduje się w klastrze kontynuacji i musi być jednym z tych 4 typów:

KONTYNUUJ: użytkownik obejrzał już ponad 1 minutę tych treści.

NOWOŚĆ: użytkownik obejrzał wszystkie dostępne odcinki niektórych odcinków, ale pojawił się nowy odcinek i jest tylko jeden nieobejrzany odcinek. Dotyczy to m.in. programów telewizyjnych, nagranych meczów piłki nożnej w jednym serialu.

DALEJ: użytkownik obejrzał co najmniej 1 pełny odcinek niektórych treści w postaci odcinków, ale pozostał dokładnie 1 odcinek lub pozostał dokładnie 1 odcinek, w którym ostatni odcinek nie jest „NOWY”. Został on opublikowany, zanim użytkownik zaczął oglądać treści w formie odcinków.

LISTA DO obejrzenia: użytkownik jednoznacznie chce dodać film, wydarzenie lub serial do listy Do obejrzenia, aby ręcznie wybrać, co chce obejrzeć w następnej kolejności.

Czas ostatniego zaangażowania Wymagane warunkowo Należy je podać, gdy element znajduje się w klastrze kontynuacji. W milisekundach epoki.
Czas ostatniej pozycji odtwarzania Wymagane warunkowo Należy podać je, gdy element znajduje się w klastrze kontynuacyjnym, a element WatchNextType ma wartość Continue. W milisekundach w epoce.

TvEpisodeEntity

Atrybut Wymóg Uwagi
Nazwa Wymagany
Obrazy plakatu Wymagany Wymagany jest co najmniej 1 obraz o współczynniku proporcji. (Preferowana jest orientacja pozioma, ale w zależności od sytuacji zalecamy przesyłanie zarówno obrazów pionowych, jak i poziomych).

Wskazówki znajdziesz w specyfikacji obrazów.

Identyfikator URI odtwarzania Wymagany

Precyzyjny link do aplikacji dostawcy, aby rozpocząć odtwarzanie odcinka.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Identyfikator URI strony z informacjami Opcjonalnie

Precyzyjny link do aplikacji dostawcy, który pozwala wyświetlić szczegóły odcinka programu telewizyjnego.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Wyświetl numer odcinka

Opcjonalny

Dostępne w wersji 1.3.1

Ciąg znaków
Data emisji Wymagany W milisekundach w epoce.
Dostępność Wymagany

AVAILABLE: treść jest dostępna dla użytkownika bez wykonywania dalszych czynności.

FREE_WITH_SUBSCRIPTION: treści są dostępne po wykupieniu subskrypcji przez użytkownika.

PAID_CONTENT: treści wymagają zakupu lub wypożyczenia przez użytkownika.

KUPIONE: treść została kupiona lub wypożyczona przez użytkownika.

Cena oferty Opcjonalnie Dowolny tekst
Czas działania Wymagany Musi być wartością dodatnią w milisekundach.
Gatunek Wymagany Dowolny tekst
Oceny treści Wymagany Tekst dowolny, zgodny ze standardem branżowym. (Przykład)
Typ „Warte obejrzenia” Wymagane warunkowo

Musisz podać go, gdy element znajduje się w klastrze kontynuacji i musi być jednym z tych 4 typów:

KONTYNUUJ: użytkownik obejrzał już ponad 1 minutę tych treści.

NOWOŚĆ: użytkownik obejrzał wszystkie dostępne odcinki niektórych odcinków, ale pojawił się nowy odcinek i jest tylko jeden nieobejrzany odcinek. Dotyczy to m.in. programów telewizyjnych, nagranych meczów piłki nożnej w jednym serialu.

DALEJ: użytkownik obejrzał co najmniej 1 pełny odcinek niektórych treści w postaci odcinków, ale pozostał dokładnie 1 odcinek lub pozostał dokładnie 1 odcinek, w którym ostatni odcinek nie jest „NOWY”. Został on opublikowany, zanim użytkownik zaczął oglądać treści w formie odcinków.

LISTA DO obejrzenia: użytkownik jednoznacznie chce dodać film, wydarzenie lub serial do listy Do obejrzenia, aby ręcznie wybrać, co chce obejrzeć w następnej kolejności.

Czas ostatniego zaangażowania Wymagane warunkowo Należy je podać, gdy element znajduje się w klastrze kontynuacji. W milisekundach epoki.
Czas ostatniej pozycji odtwarzania Wymagane warunkowo Należy podać je, gdy element znajduje się w klastrze kontynuacyjnym, a element WatchNextType ma wartość Continue. W milisekundach w epoce.

LiveStreamingVideoEntity

Atrybut Wymóg Uwagi
Nazwa Wymagany
Obrazy plakatu Wymagany Wymagany jest co najmniej 1 obraz o współczynniku proporcji. (Preferowana jest orientacja pozioma, ale w zależności od sytuacji zalecamy przesyłanie zarówno obrazów pionowych, jak i poziomych).

Wskazówki znajdziesz w specyfikacji obrazów.

Identyfikator URI odtwarzania Wymagany

Precyzyjny link do aplikacji dostawcy, aby rozpocząć odtwarzanie filmu.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

Prezenterzy Wymagany Dowolny tekst
Godzina rozpoczęcia Opcjonalnie W milisekundach w epoce.
Godzina zakończenia Opcjonalnie W milisekundach w epoce.
liczbę wyświetleń; Opcjonalnie Tekst dowolny, musi być zlokalizowany.
Typ „Warte obejrzenia” Wymagane warunkowo

Musisz podać go, gdy element znajduje się w klastrze kontynuacji i musi być jednym z tych 4 typów:

KONTYNUUJ: użytkownik obejrzał już ponad 1 minutę tych treści.

NOWOŚĆ: użytkownik obejrzał wszystkie dostępne odcinki niektórych odcinków, ale pojawił się nowy odcinek i jest tylko jeden nieobejrzany odcinek. Dotyczy to m.in. programów telewizyjnych, nagranych meczów piłki nożnej w jednym serialu.

DALEJ: użytkownik obejrzał co najmniej 1 pełny odcinek niektórych treści w postaci odcinków, ale pozostał dokładnie 1 odcinek lub pozostał dokładnie 1 odcinek, w którym ostatni odcinek nie jest „NOWY”. Został on opublikowany, zanim użytkownik zaczął oglądać treści w formie odcinków.

LISTA DO obejrzenia: użytkownik jednoznacznie chce dodać film, wydarzenie lub serial do listy Do obejrzenia, aby ręcznie wybrać, co chce obejrzeć w następnej kolejności.

Czas ostatniego zaangażowania Wymagane warunkowo Należy je podać, gdy element znajduje się w klastrze kontynuacji. W milisekundach epoki.
Czas ostatniej pozycji odtwarzania Wymagane warunkowo Należy podać je, gdy element znajduje się w klastrze kontynuacyjnym, a element WatchNextType ma wartość Continue. W milisekundach w epoce.

VideoClipEntity

Obiekt VideoClipEntity reprezentuje film pochodzący z mediów społecznościowych takich jak TikTok czy YouTube.

Atrybut Wymóg Uwagi
Nazwa Wymagany
Obrazy plakatu Wymagany Wymagany jest co najmniej 1 obraz o współczynniku proporcji. (Preferowana jest orientacja pozioma, ale w zależności od sytuacji zalecamy przesyłanie zarówno obrazów pionowych, jak i poziomych).

Wskazówki znajdziesz w specyfikacji obrazów.

Identyfikator URI odtwarzania Wymagany

Precyzyjny link do aplikacji dostawcy, aby rozpocząć odtwarzanie filmu.

Uwaga: do atrybucji możesz używać precyzyjnych linków. Przeczytaj te najczęstsze pytania

datę utworzenia; Wymagany W milisekundach w epoce.
Czas działania Wymagany Musi być wartością dodatnią w milisekundach.
Twórca Wymagany Dowolny tekst
Obraz twórcy Opcjonalnie Obraz awatara twórcy
liczbę wyświetleń; Opcjonalnie Tekst dowolny, musi być zlokalizowany.
Typ „Warte obejrzenia” Wymagane warunkowo

Musisz podać go, gdy element znajduje się w klastrze kontynuacji i musi być jednym z tych 4 typów:

KONTYNUUJ: użytkownik obejrzał już ponad 1 minutę tych treści.

NOWOŚĆ: użytkownik obejrzał wszystkie dostępne odcinki niektórych odcinków, ale pojawił się nowy odcinek i jest tylko jeden nieobejrzany odcinek. Dotyczy to m.in. programów telewizyjnych, nagranych meczów piłki nożnej w jednym serialu.

DALEJ: użytkownik obejrzał co najmniej 1 pełny odcinek niektórych treści w postaci odcinków, ale pozostał dokładnie 1 odcinek lub pozostał dokładnie 1 odcinek, w którym ostatni odcinek nie jest „NOWY”. Został on opublikowany, zanim użytkownik zaczął oglądać treści w formie odcinków.

LISTA DO obejrzenia: użytkownik jednoznacznie chce dodać film, wydarzenie lub serial do listy Do obejrzenia, aby ręcznie wybrać, co chce obejrzeć w następnej kolejności.

Czas ostatniego zaangażowania Wymagane warunkowo Należy je podać, gdy element znajduje się w klastrze kontynuacji. W milisekundach epoki.
Czas ostatniej pozycji odtwarzania Wymagane warunkowo Należy podać je, gdy element znajduje się w klastrze kontynuacyjnym, a element WatchNextType ma wartość Continue. W milisekundach w epoce.

Specyfikacja obrazu

W tej sekcji znajdziesz listę wymagań dotyczących komponentów z obrazem:

Formaty plików

PNG, JPG, statyczne pliki GIF, WebP

Maksymalny rozmiar pliku

5120 KB

Dodatkowe zalecenia

  • Bezpieczny obszar obrazu: ważne treści umieść w środkowych 80% obrazu.

Przykład

Kotlin

var movie = MovieEntity.Builder()
    .setName("Avengers")
    .addPosterImage(Image.Builder()
                          .setImageUri(Uri.parse("http://www.x.com/image.png"))
                          .setImageHeightInPixel(960)
                          .setImageWidthInPixel(408)
                          .build())
    .setPlayBackUri(Uri.parse("http://tv.com/playback/1"))
    .setReleaseDateEpochMillis(1633032895L)
    .setAvailability(ContentAvailability.AVAILABILITY_AVAILABLE)
    .setDurationMillis(12345678L)
    .addGenre("action")
    .addContentRating("R")
    .setWatchNextType(WatchNextType.TYPE_NEW)
    .setLastEngagementTimeMillis(1664568895L)
    .build()

Java

MovieEntity movie = new MovieEntity.Builder()
                  .setName("Avengers")
                  .addPosterImage(
                      new Image.Builder()
                          .setImageUri(Uri.parse("http://www.x.com/image.png"))
                          .setImageHeightInPixel(960)
                          .setImageWidthInPixel(408)
                          .build())
                  .setPlayBackUri(Uri.parse("http://tv.com/playback/1"))
                  .setReleaseDateEpochMillis(1633032895L)
                  .setAvailability(ContentAvailability.AVAILABILITY_AVAILABLE)
                  .setDurationMillis(12345678L)
                  .addGenre("action")
                  .addContentRating("R")
                  .setWatchNextType(WatchNextType.TYPE_NEW)
                  .setLastEngagementTimeMillis(1664568895L)
                  .build();

Krok 2. Podaj dane klastra

Zalecamy, aby zadanie publikowania treści było wykonywane w tle (np. za pomocą narzędzia WorkManager) i planowane regularnie lub na podstawie zdarzeń (np. za każdym razem, gdy użytkownik otworzy aplikację lub gdy tylko doda coś do koszyka).

Za publikowanie klastrów odpowiada AppEngagePublishClient. Klient udostępnia te interfejsy API:

  • isServiceAvailable
  • publishRecommendationClusters
  • publishFeaturedCluster
  • publishContinuationCluster
  • publishUserAccountManagementRequest
  • updatePublishStatus
  • deleteRecommendationsClusters
  • deleteFeaturedCluster
  • deleteContinuationCluster
  • deleteUserManagementCluster
  • deleteClusters

isServiceAvailable

Ten interfejs API służy do sprawdzania, czy usługa jest dostępna do integracji i czy treści można zaprezentować na urządzeniu.

Kotlin


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.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
}

Java


client.isServiceAvailable().addOnCompleteListener(task - > {
    if (task.isSuccessful()) {
        // Handle success
        if(task.getResult()) {
          // Service is available on the device, proceed with content publish
          // calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
});

publishRecommendationClusters

Ten interfejs API służy do publikowania listy obiektów RecommendationCluster.

Kotlin


client.publishRecommendationClusters(
      PublishRecommendationClustersRequest.Builder()
        .addRecommendationCluster(
          RecommendationCluster.Builder()
            .addEntity(entity1)
            .addEntity(entity2)
            .setTitle("Top Picks For You")
            .build()
        )
        .build()
    )

Java


client.publishRecommendationClusters(
            new PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    new RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Top Picks For You")
                        .build())
                .build());

Gdy usługa otrzyma żądanie, w ramach jednej transakcji wykonywane są te działania:

  • Dotychczasowe dane aplikacji RecommendationCluster od partnera dewelopera zostaną usunięte.
  • Dane z żądania są analizowane i przechowywane w zaktualizowanym klastrze rekomendacji.

W przypadku błędu całe żądanie jest odrzucane, a istniejący stan zostaje zachowany.

publishFeaturedCluster

Ten interfejs API służy do publikowania listy obiektów FeaturedCluster.

Kotlin


client.publishFeaturedCluster(
    PublishFeaturedClusterRequest.Builder()
      .setFeaturedCluster(
        FeaturedCluster.Builder()
          .addEntity(entity1)
          .addEntity(entity2)
          .build())
      .build())

Java


client.publishFeaturedCluster(
            new PublishFeaturedClustersRequest.Builder()
                .addFeaturedCluster(
                    new FeaturedCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .build())
                .build());

Gdy usługa otrzyma żądanie, w ramach jednej transakcji wykonywane są te działania:

  • Dotychczasowe dane aplikacji FeaturedCluster od partnera dewelopera zostaną usunięte.
  • Dane z żądania są analizowane i przechowywane w zaktualizowanym klastrze Polecane.

W przypadku błędu całe żądanie jest odrzucane, a istniejący stan zostaje zachowany.

publishContinuationCluster

Ten interfejs API służy do publikowania obiektu ContinuationCluster.

Kotlin


client.publishContinuationCluster(
    PublishContinuationClusterRequest.Builder()
      .setContinuationCluster(
        ContinuationCluster.Builder()
          .addEntity(entity1)
          .addEntity(entity2)
          .build())
      .build())

Java


client.publishContinuationCluster(
            new PublishContinuationClusterRequest.Builder()
                .setContinuationCluster(
                    new ContinuationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .build())
                .build());

Gdy usługa otrzyma żądanie, w ramach jednej transakcji wykonywane są te działania:

  • Dotychczasowe dane aplikacji ContinuationCluster od partnera dewelopera zostaną usunięte.
  • Dane z żądania są analizowane i przechowywane w zaktualizowanym klastrze kontynuacji.

W przypadku błędu całe żądanie jest odrzucane, a istniejący stan zostaje zachowany.

publishUserAccountManagementRequest

Ten interfejs API służy do publikowania karty logowania . Użytkownicy są kierowani na stronę logowania w aplikacji, na której mogą publikować treści (lub udostępniać im bardziej spersonalizowane treści).

Te metadane są częścią karty logowania –

Atrybut Wymóg Opis
Identyfikator URI działania Wymagane Precyzyjny link do działania (np. do strony logowania w aplikacji)
Obraz Opcjonalnie – jeśli nie podano tytułu, należy podać tytuł

Obraz widoczny na karcie

obrazy o współczynniku proporcji 16 x 9 i rozdzielczości 1264 x 712,

tytuł; Opcjonalnie – jeśli nie podano, należy przesłać obraz. Tytuł na karcie
Tekst działania Opcjonalnie Tekst wyświetlany w wezwaniu do działania (np. „Zaloguj się”)
Podtytuł Opcjonalnie Opcjonalne napisy na karcie

Kotlin


var SIGN_IN_CARD_ENTITY =
      SignInCardEntity.Builder()
          .addPosterImage(
              Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build()

client.publishUserAccountManagementRequest(
            PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());

Java


SignInCardEntity SIGN_IN_CARD_ENTITY =
      new SignInCardEntity.Builder()
          .addPosterImage(
              new Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build();

client.publishUserAccountManagementRequest(
            new PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());

Gdy usługa otrzyma żądanie, w ramach jednej transakcji wykonywane są te działania:

  • Dotychczasowe dane UserAccountManagementCluster od partnera dewelopera zostaną usunięte.
  • Dane z żądania są analizowane i przechowywane w zaktualizowanym klastrze UserAccountManagementCluster.

W przypadku błędu całe żądanie jest odrzucane, a istniejący stan zostaje zachowany.

updatePublishStatus

Jeśli z jakichkolwiek wewnętrznych powodów biznesowych nie zostanie opublikowany żaden z klastrów, zdecydowanie zalecamy zaktualizowanie stanu publikacji za pomocą interfejsu API updatePublishStatus. To ważne, ponieważ :

  • Podanie stanu we wszystkich scenariuszach, nawet po opublikowaniu treści (STAN == OPUBLIKOWANO), ma kluczowe znaczenie przy wypełnianiu paneli, które korzystają z tego jednoznacznego stanu do przekazywania informacji o stanie i innych wskaźnikach integracji.
  • Jeśli treści nie są opublikowane, ale stan integracji nie jest uszkodzony (STATUS == NOT_OpublikujED), Google może uniknąć aktywowania alertów w panelach stanu aplikacji. Jest to potwierdzenie, że treści nie zostały opublikowane z powodu oczekiwanej sytuacji z punktu widzenia dostawcy.
  • Dzięki temu deweloperzy mogą określić, kiedy dane są publikowane, a kiedy nie.
  • Google może używać kodów stanu, aby skłonić użytkownika do wykonania określonych działań w aplikacji, co pozwoli mu zobaczyć zawartość aplikacji lub ją przezwyciężyć.

Lista kodów stanu kwalifikującego się do publikacji :

// Content is published
AppEngagePublishStatusCode.PUBLISHED,

// Content is not published as user is not signed in
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN,

// Content is not published as user is not subscribed
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SUBSCRIPTION,

// Content is not published as user location is ineligible
AppEngagePublishStatusCode.NOT_PUBLISHED_INELIGIBLE_LOCATION,

// Content is not published as there is no eligible content
AppEngagePublishStatusCode.NOT_PUBLISHED_NO_ELIGIBLE_CONTENT,

// Content is not published as the feature is disabled by the client
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_FEATURE_DISABLED_BY_CLIENT,

// Content is not published as the feature due to a client error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_CLIENT_ERROR,

// Content is not published as the feature due to a service error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_SERVICE_ERROR,

// Content is not published due to some other reason
// Reach out to engage-developers@ before using this enum.
AppEngagePublishStatusCode.NOT_PUBLISHED_OTHER

Jeśli treści nie zostały opublikowane, ponieważ użytkownik nie jest zalogowany, zalecamy opublikowanie karty logowania. Jeśli z jakiegoś powodu dostawcy nie mogą opublikować karty logowania, zalecamy wywołanie interfejsu API updatePublishStatus z kodem stanu NOT_OpublikujED_REQUIRES_SIGN_IN.

Kotlin


client.updatePublishStatus(
   PublishStatusRequest.Builder()
     .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
     .build())

Java


client.updatePublishStatus(
    new PublishStatusRequest.Builder()
        .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
        .build());

deleteRecommendationClusters

Ten interfejs API służy do usuwania zawartości klastrów rekomendacji.

Kotlin


client.deleteRecommendationClusters()

Java


client.deleteRecommendationClusters();

Gdy usługa otrzyma żądanie, usunie istniejące dane z klastrów rekomendacji. W przypadku błędu całe żądanie jest odrzucane, a obecny stan zostaje zachowany.

deleteFeaturedCluster

Ten interfejs API służy do usuwania zawartości polecanego klastra.

Kotlin


client.deleteFeaturedCluster()

Java


client.deleteFeaturedCluster();

Po otrzymaniu żądania usługa usuwa istniejące dane z polecanego klastra. W przypadku błędu całe żądanie jest odrzucane, a obecny stan zostaje zachowany.

deleteContinuationCluster

Ten interfejs API służy do usuwania zawartości klastra kontynuacji.

Kotlin


client.deleteContinuationCluster()

Java


client.deleteContinuationCluster();

Gdy usługa otrzyma żądanie, usunie istniejące dane z klastra kontynuacji. W przypadku błędu całe żądanie jest odrzucane, a obecny stan zostaje zachowany.

deleteUserManagementCluster

Ten interfejs API służy do usuwania zawartości klastra UserAccountManagement.

Kotlin


client.deleteUserManagementCluster()

Java


client.deleteUserManagementCluster();

Po otrzymaniu żądania usługa usuwa istniejące dane z klastra UserAccountManagement. W przypadku błędu całe żądanie jest odrzucane, a bieżący stan zostaje zachowany.

deleteClusters

Ten interfejs API służy do usuwania treści określonego typu klastra.

Kotlin


client.deleteClusters(
    DeleteClustersRequest.Builder()
      .addClusterType(ClusterType.TYPE_CONTINUATION)
      .addClusterType(ClusterType.TYPE_FEATURED)
      .addClusterType(ClusterType.TYPE_RECOMMENDATION)
      .build())

Java


client.deleteClusters(
            new DeleteClustersRequest.Builder()
                .addClusterType(ClusterType.TYPE_CONTINUATION)
                .addClusterType(ClusterType.TYPE_FEATURED)
                .addClusterType(ClusterType.TYPE_RECOMMENDATION)
                .build());

Gdy usługa otrzymuje żądanie, usuwa istniejące dane ze wszystkich klastrów pasujących do określonych typów klastrów. Klienty mogą przekazywać 1 lub wiele typów klastrów. W przypadku błędu całe żądanie jest odrzucane, a obecny stan zostaje zachowany.

Obsługa błędów

Zdecydowanie zalecamy wsłuchiwanie się w wynik zadania z interfejsów API publikowania, aby można było podjąć dalsze działania w celu odzyskania udanego zadania i ponownego przesłania go.

Kotlin


client.publishRecommendationClusters(
        PublishRecommendationClustersRequest.Builder()
          .addRecommendationCluster(..)
          .build())
      .addOnCompleteListener { task ->
        if (task.isSuccessful) {
          // do something
        } else {
          val exception = task.exception
          if (exception is AppEngageException) {
            @AppEngageErrorCode val errorCode = exception.errorCode
            if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
              // do something
            }
          }
        }
      }

Java


client.publishRecommendationClusters(
              new PublishRecommendationClustersRequest.Builder()
                  .addRecommendationCluster(...)
                  .build())
          .addOnCompleteListener(
              task -> {
                if (task.isSuccessful()) {
                  // do something
                } else {
                  Exception exception = task.getException();
                  if (exception instanceof AppEngageException) {
                    @AppEngageErrorCode
                    int errorCode = ((AppEngageException) exception).getErrorCode();
                    if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
                      // do something
                    }
                  }
                }
              });

Błąd jest zwracany jako AppEngageException, a przyczyna jest podana w postaci kodu błędu.

Kod błędu Uwaga
SERVICE_NOT_FOUND Usługa jest niedostępna na danym urządzeniu.
SERVICE_NOT_AVAILABLE Usługa jest dostępna na danym urządzeniu, ale nie jest dostępna w momencie połączenia (na przykład jest wyraźnie wyłączona).
SERVICE_CALL_EXECUTION_FAILURE Nie udało się wykonać zadania z powodu problemów z wątkiem. W takim przypadku można spróbować ponownie.
SERVICE_CALL_PERMISSION_DENIED Rozmówca nie może nawiązać połączenia z usługą.
SERVICE_CALL_INVALID_ARGUMENT Żądanie zawiera nieprawidłowe dane (na przykład więcej niż dozwolona liczba klastrów).
SERVICE_CALL_INTERNAL Po stronie usługi wystąpił błąd.
SERVICE_CALL_RESOURCE_EXHAUSTED Wywoływanie usługi jest wykonywane zbyt często.

Krok 3. Obsługuj intencje transmisji

Oprócz wykonywania wywołań interfejsu Content API w zadaniu musisz też skonfigurować BroadcastReceiver, aby odbierać żądanie opublikowania treści.

Intencje dotyczące przesyłania służą głównie do reaktywacji aplikacji i wymuszania synchronizacji danych. Intencje transmisji nie są przeznaczone do wysyłania zbyt często. Jest wywoływane tylko wtedy, gdy usługa dla Agencji stwierdzi, że treści mogą być nieaktualne (np. sprzed tygodnia). Dzięki temu zyska on większą pewność, że użytkownik będzie mógł korzystać z nowych treści, nawet jeśli aplikacja nie była uruchamiana od dłuższego czasu.

BroadcastReceiver należy skonfigurować na dwa sposoby:

  • Dynamicznie zarejestruj instancję klasy BroadcastReceiver za pomocą Context.registerReceiver(). Umożliwia to komunikację z aplikacji, które wciąż są zapisane w pamięci.

Kotlin

class AppEngageBroadcastReceiver : BroadcastReceiver(){
  // Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast
  // is received
  // Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received
  // Trigger continuation cluster publish when PUBLISH_CONTINUATION broadcast is
  // received
}

fun registerBroadcastReceivers(context: Context){
  var  context = context
  context = context.applicationContext

// Register Recommendation Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_RECOMMENDATION))

// Register Featured Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_FEATURED))

// Register Continuation Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_CONTINUATION))
}

Java

class AppEngageBroadcastReceiver extends BroadcastReceiver {
// Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast
// is received

// Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received

// Trigger continuation cluster publish when PUBLISH_CONTINUATION broadcast is
// received
}

public static void registerBroadcastReceivers(Context context) {

context = context.getApplicationContext();

// Register Recommendation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_RECOMMENDATION));

// Register Featured Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_FEATURED));

// Register Continuation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_CONTINUATION));

}
  • Statycznie zadeklaruj implementację za pomocą tagu <receiver> w pliku AndroidManifest.xml. Dzięki temu aplikacja może odbierać komunikaty, gdy nie jest uruchomiona, oraz publikować treści.
<application>
   <receiver
      android:name=".AppEngageBroadcastReceiver"
      android:exported="true"
      android:enabled="true">
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_RECOMMENDATION" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_FEATURED" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_CONTINUATION" />
      </intent-filter>
   </receiver>
</application>

Usługa wysyła te zamiary:

  • com.google.android.engage.action.PUBLISH_RECOMMENDATION Zalecamy uruchomienie wywołania publishRecommendationClusters przy odbieraniu tej intencji.
  • com.google.android.engage.action.PUBLISH_FEATURED Zalecamy uruchomienie wywołania publishFeaturedCluster po otrzymaniu tej intencji.
  • com.google.android.engage.action.PUBLISH_CONTINUATION Gdy odbierasz tę intencję, zalecamy uruchomienie wywołania publishContinuationCluster.

Przepływ pracy w integracji

Szczegółowy przewodnik dotyczący weryfikowania integracji po jej zakończeniu znajdziesz w artykule o procesie integracji programistycznej Google Workspace.

Najczęstsze pytania

Zapoznaj się z odpowiedziami na najczęstsze pytania dotyczące pakietu SDK dla Agencji.

Kontakt

Jeśli masz pytania dotyczące procesu integracji, wyślij e-maila na adres engagement-developers@google.com.

Dalsze kroki

Po zakończeniu integracji wykonaj te czynności:

  • Wyślij e-maila na adres Engage-developers@google.com i załącz zintegrowany pakiet APK, który jest gotowy do przetestowania przez Google.
  • Google przeprowadza weryfikację i weryfikację wewnętrzną, aby mieć pewność, że integracja działa zgodnie z oczekiwaniami. Jeśli potrzebne będą zmiany, Google skontaktuje się z Tobą, aby przekazać Ci niezbędne informacje.
  • Gdy testy zostaną ukończone i nie będą wymagane żadne zmiany, Google skontaktuje się z Tobą, aby powiadomić Cię, że możesz rozpocząć publikowanie zaktualizowanego i zintegrowanego pakietu APK w Sklepie Play.
  • Gdy Google potwierdzi, że zaktualizowany plik APK został opublikowany w Sklepie Play, klastry Rekomendacja, Polecane i Kontynuacja mogą zostać opublikowane i widoczne dla użytkowników.