Ten przewodnik zawiera instrukcje dotyczące udostępniania deweloperom danych o subskrypcji aplikacji i uprawnieniach w Google TV za pomocą pakietu SDK Engage. Użytkownicy mogą znaleźć treści, do których mają dostęp, i umożliwić Google TV wyświetlanie trafnych rekomendacji treści bezpośrednio w Google TV na telewizorze, komórce i tablecie.
Wymagania wstępne
Zanim zaczniesz korzystać z interfejsu API uprawnień urządzenia, musisz utworzyć plik danych z działaniami dotyczącymi multimediów. Jeśli nie został jeszcze przeprowadzony, przeprowadź proces wdrażania przekazu działań z mediami.
Przygotowanie
Zanim zaczniesz, wykonaj te czynności: Sprawdź, czy Twoja aplikacja jest kierowana na interfejs API na poziomie 19 lub nowszym.
Dodaj bibliotekę
com.google.android.engage
do aplikacji:Do integracji służą osobne pakiety SDK: jeden do aplikacji mobilnych, a drugi do aplikacji na telewizory.
Urządzenia mobilne
dependencies { implementation 'com.google.android.engage:engage-core:1.5.5 }
do telewizora
dependencies { implementation 'com.google.android.engage:engage-tv:1.0.2 }
W pliku
AndroidManifest.xml
ustaw środowisko usługi Engage na produkcyjne.Aplikacja mobilna w formacie APK
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
Aplikacja na telewizory
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
Zanim wyślesz plik APK do Google, ustaw środowisko usługi engage na „production” w pliku AndroidManifest.xml. Aby zapewnić optymalną wydajność i kompatybilność w przyszłości, publikuj dane tylko wtedy, gdy aplikacja jest na pierwszym planie i użytkownik aktywnie z niej korzysta, np. podczas uruchamiania aplikacji, po zalogowaniu się lub podczas aktywnego korzystania. Nie zalecamy publikowania z procesów w tle.
publikować informacje o subskrypcji w przypadku tych zdarzeń:
- Użytkownik loguje się w aplikacji.
- Użytkownik przełącza się między profilami (jeśli są obsługiwane).
- Użytkownik kupuje nową subskrypcję.
- Użytkownik ulepsza obecną subskrypcję.
- Subskrypcja użytkownika wygasa.
Integracja
W tej sekcji znajdziesz niezbędne przykłady kodu i instrukcje implementowania funkcji AccountProfile
i SubscriptionEntity
, aby zarządzać różnymi typami subskrypcji.
Konto i profil użytkownika
Aby umożliwić korzystanie z funkcji personalizacji na Google TV, podaj informacje o koncie. Użyj AccountProfile
, aby podać:
- Identyfikator konta: unikalny identyfikator reprezentujący konto użytkownika. Może to być rzeczywisty identyfikator konta lub odpowiednio zaciemniona wersja.
// Set the account ID to which the subscription applies.
// Don't set the profile ID because subscription applies to account level.
val accountProfile = AccountProfile.Builder()
.setAccountId("user_account_id")
.setProfileId("user_profile id")
.build();
Subskrypcja poziomu wspólnego
W przypadku użytkowników z podstawowymi subskrypcjami usług dostawcy mediów, np. usługa z jednym poziomem abonamentu, który zapewnia dostęp do wszystkich płatnych treści, podaj te podstawowe informacje:
Typ subskrypcji: wyraźnie określ konkretny abonament użytkownika.
SUBSCRIPTION_TYPE_ACTIVE
: użytkownik ma aktywną płatną subskrypcję.SUBSCRIPTION_TYPE_ACTIVE_TRIAL
: użytkownik ma subskrypcję próbną.SUBSCRIPTION_TYPE_INACTIVE
: użytkownik ma konto, ale nie ma aktywnej subskrypcji ani wersji próbnej.
Czas ważności: opcjonalny czas w milisekundach. Określ, kiedy subskrypcja ma wygasnąć.
Nazwa pakietu dostawcy: podaj nazwę pakietu aplikacji, która obsługuje subskrypcję.
Przykład: plik danych dostawcy mediów Sample
"actionAccessibilityRequirement": [
{
"@type": "ActionAccessSpecification",
"category": "subscription",
"availabilityStarts": "2022-06-01T07:00:00Z",
"availabilityEnds": "2026-05-31T07:00:00Z",
"requiresSubscription": {
"@type": "MediaSubscription",
// Don't match this string,
// ID is only used to for reconciliation purpose
"@id": "https://www.example.com/971bfc78-d13a-4419",
// Don't match this, as name is only used for displaying purpose
"name": "Basic common name",
"commonTier": true
}
W tym przykładzie tworzymy SubscriptionEntity
dla użytkownika:
val subscription = SubscriptionEntity
.Builder()
setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("com.google.android.example")
// Optional
// December 30, 2025 12:00:00AM in milliseconds since epoch
.setExpirationTimeMillis(1767052800000)
.build();
Subskrypcja Premium
Jeśli aplikacja oferuje wielopoziomowe pakiety subskrypcji premium, które obejmują rozszerzone treści lub funkcje wykraczające poza poziom podstawowy, należy to zaznaczyć, dodając do subskrypcji co najmniej 1 uprawnienie.
To uprawnienie ma te pola:
- Identyfikator: wymagany ciąg znaków identyfikatora uprawnień. Musi on odpowiadać jednemu z identyfikatorów uprawnień (nie jest to pole identyfikatora) podanego w pliku danych dostawcy mediów opublikowanym na Google TV.
- Imię i nazwisko: ta informacja jest pomocnicza i służy do dopasowywania uprawnień. Podanie nazwy uprawnień w formie zrozumiałej dla człowieka ułatwia zrozumienie uprawnień użytkowników zarówno deweloperom, jak i zespołom pomocy. Na przykład: Sling Orange.
- Expiration TimeMillis: opcjonalnie podaj czas ważności w milisekundach dla tego uprawnienia, jeśli różni się on od czasu ważności subskrypcji. Domyślnie uprawnienia wygasają wraz z zakończeniem subskrypcji.
W przypadku tego przykładowego fragmentu pliku danych dostawcy mediów:
"actionAccessibilityRequirement": [
{
"@type": "ActionAccessSpecification",
"category": "subscription",
"availabilityStarts": "2022-06-01T07:00:00Z",
"availabilityEnds": "2026-05-31T07:00:00Z",
"requiresSubscription": {
"@type": "MediaSubscription",
// Don't match this string,
// ID is only used to for reconciliation purpose
"@id": "https://www.example.com/971bfc78-d13a-4419",
// Don't match this, as name is only used for displaying purpose
"name": "Example entitlement name",
"commonTier": false,
// match this identifier in your API. This is the crucial
// entitlement identifier used for recommendation purpose.
"identifier": "example.com:entitlementString1"
}
W tym przykładzie tworzymy SubscriptionEntity
dla subskrybowanego użytkownika:
// Subscription with entitlements.
// The entitlement expires at the same time as its subscription.
val subscription = SubscriptionEntity
.Builder()
.setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("com.google.android.example")
// Optional
// December 30, 2025 12:00:00AM in milliseconds
.setExpirationTimeMillis(1767052800000)
.addEntitlement(
SubscriptionEntitlement.Builder()
// matches with the identifier in media provider feed
.setEntitlementId("example.com:entitlementString1")
.setDisplayName("entitlement name1")
.build()
)
.build();
// Subscription with entitlements
// The entitement has different expiration time from its subscription
val subscription = SubscriptionEntity
.Builder()
.setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("com.google.android.example")
// Optional
// December 30, 2025 12:00:00AM in milliseconds
.setExpirationTimeMillis(1767052800000)
.addEntitlement(
SubscriptionEntitlement.Builder()
.setEntitlementId("example.com:entitlementString1")
.setDisplayName("entitlement name1")
// You may set the expiration time for entitlement
// December 15, 2025 10:00:00 AM in milliseconds
.setExpirationTimeMillis(1765792800000)
.build())
.build();
Subskrypcja połączonego pakietu usług
Subskrypcje zwykle należą do dostawcy multimediów aplikacji źródłowej, ale można je przypisać do powiązanego pakietu usług, podając nazwę tego pakietu w subskrypcji.
Poniższy przykładowy kod pokazuje, jak utworzyć subskrypcję użytkownika.
// Subscription for linked service package
val subscription = SubscriptionEntity
.Builder()
.setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("com.google.android.example")
// Optional
// December 30, 2025 12:00:00AM in milliseconds since epoch
.setExpirationTimeMillis(1767052800000)
.build();
Jeśli użytkownik ma też inną subskrypcję usługi dodatkowej, dodaj kolejną subskrypcję i odpowiednio ustaw nazwę pakietu usług powiązanych.
// Subscription for linked service package
val linkedSubscription = Subscription
.Builder()
.setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("linked service package name")
// Optional
// December 30, 2025 12:00:00AM in milliseconds since epoch
.setExpirationTimeMillis(1767052800000)
.addBundledSubscription(
BundledSubscription.Builder()
.setBundledSubscriptionProviderPackageName(
"bundled-subscription-package-name"
)
.setSubscriptionType(SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE)
.setExpirationTimeMillis(111)
.addEntitlement(
SubscriptionEntitlement.Builder()
.setExpirationTimeMillis(111)
.setDisplayName("Silver subscription")
.setEntitlementId("subscription.tier.platinum")
.build()
)
.build()
)
.build();
Opcjonalnie możesz też dodać uprawnienia do połączonej subskrypcji usługi.
Podanie zestawu subskrypcji
Uruchom zadanie publikowania treści, gdy aplikacja działa na pierwszym planie.
Aby opublikować obiekt SubscriptionCluster
, użyj metody publishSubscriptionCluster()
z klasy AppEngagePublishClient
.
Użyj isServiceAvailable
, aby sprawdzić, czy usługa jest dostępna do integracji.
client.publishSubscription(
PublishSubscriptionRequest.Builder()
.setAccountProfile(accountProfile)
.setSubscription(subscription)
.build();
)
Użyj funkcji setSubscription()
, aby sprawdzić, czy użytkownik powinien mieć tylko jedną subskrypcję usługi.
Użyj funkcji addLinkedSubscription()
lub addLinkedSubscriptions()
, która akceptuje listę połączonych subskrypcji, aby umożliwić użytkownikowi połączenie z co najmniej 1 subskrypcją.
Gdy usługa otrzyma prośbę, utworzy nowy wpis, a stary zostanie automatycznie usunięty po 60 dniach. System zawsze używa najnowszego wpisu. W przypadku błędu cała prośba jest odrzucana, a obecny stan jest zachowany.
Aktualizuj subskrypcję
- Aby natychmiast aktualizować stan subskrypcji, wywołuj funkcję
publishSubscriptionCluster()
za każdym razem, gdy nastąpi zmiana stanu subskrypcji użytkownika, np. aktywacja, dezaktywacja, uaktualnienie lub obniżenie poziomu. Aby regularnie sprawdzać dokładność, co najmniej raz w miesiącu wywołuj funkcję
publishSubscriptionCluster()
.Aby usunąć dane z funkcji odkrywania filmów, ręcznie usuń dane użytkownika z serwera Google TV przed upływem standardowego 60-dniowego okresu przechowywania. W tym celu użyj metody
client.deleteClusters()
. Spowoduje to usunięcie wszystkich dotychczasowych danych dotyczących odkrywania filmów z profilu konta lub całego konta w zależności od wybranegoDeleteReason
.Fragment kodu służący do anulowania subskrypcji użytkownika
// If the user logs out from your media app, you must make the following call // to remove subscription and other video discovery data from the current // google TV device. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile( AccountProfile .Builder() .setAccountId() .setProfileId() .build() ) .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT) .build() ) ``` Following code snippet demonstrates removal of user subscription when user revokes the consent. ```Kotlin // If the user revokes the consent to share across device, make the call // to remove subscription and other video discovery data from all google // TV devices. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile( AccountProfile .Builder() .setAccountId() .setProfileId() .build() ) .setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT) .build() ) ``` Following code demonstrates how to remove subscription data on user profile deletion. ```Kotlin // If the user delete a specific profile, you must make the following call // to remove subscription data and other video discovery data. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile( AccountProfile .Builder() .setAccountId() .setProfileId() .build() ) .setReason(DeleteReason.DELETE_REASON_ACCOUNT_PROFILE_DELETION) .build() )
Testowanie
W tej sekcji znajdziesz szczegółowe instrukcje testowania wdrożenia subskrypcji. Przed uruchomieniem sprawdź, czy dane są prawidłowe i czy wszystko działa prawidłowo.
Lista kontrolna publikowania integracji
Publikowanie powinno nastąpić, gdy aplikacja jest na pierwszym planie, a użytkownik aktywnie z niej korzysta.
Opublikuj, gdy:
- Użytkownik loguje się po raz pierwszy.
- Użytkownik zmienia profil (jeśli profile są obsługiwane).
- Użytkownik kupuje nową subskrypcję.
- Użytkownik przechodzi na wyższą subskrypcję.
- Subskrypcja użytkownika wygasa.
Sprawdź, czy aplikacja prawidłowo wywołuje interfejsy API
isServiceAvailable()
ipublishClusters()
w logcat w przypadku zdarzeń publikowania.Sprawdź, czy dane są widoczne w aplikacji do weryfikacji. Aplikacja do weryfikacji powinna wyświetlać subskrypcję jako osobny wiersz. Gdy wywołasz interfejs API publikowania, dane powinny pojawić się w aplikacji weryfikacyjnej.
- Sprawdź, czy flaga usługi Engage NIE jest ustawiona na „produkcja” w pliku manifestu aplikacji na Androida.
- Zainstaluj i otwórz aplikację Engage Verification.
- Jeśli wartość
isServiceAvailable
w aplikacji do weryfikacji tofalse
, kliknij w niej przyciskToggle
, aby ustawić ją natrue
. - Wpisz nazwę pakietu aplikacji. Automatycznie wyświetli ona opublikowane dane.
Otwórz aplikację i wykonaj te czynności:
- Zaloguj się.
- przełączać się między profilami (jeśli jest to obsługiwane).
- Kup nową subskrypcję.
- Uaktualnij istniejącą subskrypcję.
- wygaśnięcie subskrypcji,
Weryfikowanie integracji
Aby przetestować integrację, użyj aplikacji do weryfikacji.
Aplikacja weryfikacyjna to aplikacja na Androida, której programiści mogą używać do sprawdzania, czy integracja działa prawidłowo. Aplikacja zawiera funkcje, które pomagają deweloperom weryfikować dane i intencje transmisji. Pomaga to zweryfikować dokładność danych i prawidłowe działanie przed publikacją.
- W przypadku każdego zdarzenia sprawdź, czy aplikacja wywołała interfejs API
publishSubscription
. Sprawdź opublikowane dane w aplikacji do weryfikacji. Sprawdź, czy wszystko jest zaznaczone na zielono w aplikacji do weryfikacji Jeśli wszystkie informacje o danym elemencie są prawidłowe, wyświetla się zielona ikona potwierdzenia „Wszystko w porządku” we wszystkich elementach.
Rysunek 1. Subskrypcja została aktywowana Problemy są też wyróżnione w aplikacji weryfikacyjnej
Rysunek 2. Nieudana subskrypcja Aby zobaczyć problemy w ramach subskrypcji z pakietem, użyj pilota telewizora, aby wybrać tę konkretną subskrypcję z pakietem, a następnie kliknij, aby wyświetlić problemy. Być może najpierw trzeba będzie wybrać wiersz i przesunąć w prawo, aby znaleźć kartę Subskrypcja w pakiecie. Problemy są wyróżnione na czerwono (patrz rys. 3). Użyj pilota, aby przejść w dół i sprawdzić problemy z uprawnieniami w ramach subskrypcji z pakietem.
Rysunek 3. Błędy subskrypcji Aby zobaczyć problemy w ramach uprawnień, użyj pilota do telewizora, aby skupić się na konkretnych uprawnieniach, a następnie kliknij, aby zobaczyć problemy. Problemy są wyróżnione na czerwono.
Rysunek 4. Szczegóły błędu subskrypcji