Ten przewodnik zawiera instrukcje dla deweloperów dotyczące udostępniania danych o subskrypcjach i uprawnieniach w aplikacji w Google TV za pomocą pakietu Engage SDK. Użytkownicy mogą wyszukiwać treści, do których mają dostęp, i włączać Google TV, aby otrzymywać bardzo trafne rekomendacje treści bezpośrednio w Google TV na telewizorze, telefonie i tablecie.
Wymagania wstępne
Zanim zaczniesz korzystać z interfejsu Device Entitlement API, musisz przejść proces wprowadzania do kanału działań związanych z multimediami. Jeśli jeszcze tego nie zrobiono, przeprowadź proces wprowadzania pliku danych z działaniami dotyczącymi multimediów.
Przygotowanie
Zanim zaczniesz, wykonaj te czynności: Sprawdź, czy Twoja aplikacja jest kierowana na interfejs API na poziomie 19 lub wyższym.
Dodaj bibliotekę
com.google.android.engage
do 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.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.W przypadku pliku APK na urządzenia mobilne
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
Plik APK na telewizor
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
Zanim wyślesz pakiet APK do Google, ustaw w pliku AndroidManifest.xml środowisko usługi angażującej na produkcyjne. Aby uzyskać optymalną skuteczność i zapewnić zgodność w przyszłości, publikuj dane tylko wtedy, gdy aplikacja jest na pierwszym planie, a użytkownik aktywnie z niej korzysta, np. podczas uruchamiania aplikacji, po zalogowaniu lub w trakcie aktywnego korzystania z niej. Publikowanie z procesów w tle jest odradzane.
Publikuj informacje o subskrypcji w przypadku tych zdarzeń:
- Użytkownik loguje się w Twojej aplikacji.
- Użytkownik przełącza się między profilami (jeśli są obsługiwane).
- Użytkownik kupuje nową subskrypcję.
- Użytkownik przechodzi na wyższą wersję obecnej subskrypcji.
- Subskrypcja użytkownika wygasa.
Integracja
W tej sekcji znajdziesz przykłady kodu i instrukcje wdrażania funkcji AccountProfile
i SubscriptionEntity
do zarządzania różnymi typami subskrypcji.
Konto i profil użytkownika
Aby włączyć spersonalizowane funkcje w Google TV, podaj informacje o koncie. Użyj AccountProfile
, aby podać:
- Identyfikator konta: unikalny identyfikator konta 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 na poziomie wspólnym
W przypadku użytkowników z podstawową subskrypcją usług dostawców treści, np. usługi z jednym poziomem subskrypcji, który zapewnia dostęp do wszystkich płatnych treści, podaj te podstawowe informacje:
Typ subskrypcji: wyraźnie wskaż konkretny abonament, z którego korzysta użytkownik.
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 okresu próbnego.
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 dla przykładowego 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": "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 zwykły poziom, dodaj do subskrypcji co najmniej 1 uprawnienie.
To uprawnienie ma te pola:
- Identyfikator: wymagany ciąg znaków identyfikatora dla tego uprawnienia. Musi on być zgodny z jednym z identyfikatorów uprawnień (zwróć uwagę, że nie jest to pole identyfikatora) podanych w pliku danych dostawcy treści opublikowanym w Google TV.
- Nazwa: to informacje pomocnicze używane do dopasowywania uprawnień. Podanie nazwy uprawnienia w formie czytelnej dla człowieka jest opcjonalne, ale ułatwia programistom i zespołom pomocy zrozumienie uprawnień użytkowników. Na przykład Sling Orange.
- ExpirationTimeMillis: opcjonalnie podaj czas wygaśnięcia w milisekundach dla tego uprawnienia, jeśli różni się od czasu wygaśnięcia subskrypcji. Domyślnie uprawnienia wygasają wraz z wygaśnięciem subskrypcji.
Dla 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"
}
Poniższy przykład tworzy SubscriptionEntity
dla subskrybującego 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 pakietu połączonych usług
Subskrypcje należą zwykle do dostawcy mediów w aplikacji, z której pochodzą, ale można je przypisać do połączonego pakietu usług, podając w subskrypcji nazwę połączonego pakietu usług.
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ż subskrypcję usługi dodatkowej, dodaj kolejną subskrypcję i odpowiednio ustaw nazwę pakietu połączonej usługi.
// 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.
Podaj zestaw 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 setSubscription()
, aby sprawdzić, czy użytkownik powinien mieć tylko 1 subskrypcję usługi.
Użyj addLinkedSubscription()
lub addLinkedSubscriptions()
, które akceptują listę połączonych subskrypcji, aby umożliwić użytkownikowi posiadanie zera lub większej liczby połączonych subskrypcji.
Gdy usługa otrzyma prośbę, tworzony jest nowy wpis, a stary wpis jest automatycznie usuwany po 60 dniach. System zawsze używa najnowszego wpisu. W przypadku błędu całe żądanie jest odrzucane, a dotychczasowy stan jest zachowywany.
Aktualizowanie subskrypcji
- Aby natychmiast informować o zmianach, wywołuj funkcję
publishSubscriptionCluster()
za każdym razem, gdy zmieni się stan subskrypcji użytkownika, np. w przypadku aktywacji, dezaktywacji, uaktualnienia lub obniżenia wersji. Aby regularnie weryfikować bieżącą dokładność, wywołuj funkcję
publishSubscriptionCluster()
co najmniej raz w miesiącu.Aby usunąć dane dotyczące odkrywania filmów, ręcznie usuń dane użytkownika z serwera Google TV przed upływem standardowego 60-dniowego okresu przechowywania, korzystając z
client.deleteClusters()
. Spowoduje to usunięcie wszystkich dotychczasowych danych dotyczących odkrywania filmów w profilu konta lub na całym koncie w zależności od podanegoDeleteReason
.Fragment kodu służący do usuwania 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ź dokładność danych i prawidłowe działanie.
Lista kontrolna publikowania integracji
Publikowanie powinno następować, gdy aplikacja jest na pierwszym planie i 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 podczas publikowania zdarzeń.Sprawdź, czy dane są widoczne w aplikacji weryfikacyjnej. Aplikacja weryfikacyjna powinna wyświetlać subskrypcję w osobnym wierszu. Gdy zostanie wywołany interfejs API publikowania, dane powinny pojawić się w aplikacji weryfikacyjnej.
- Sprawdź, czy w pliku manifestu aplikacji na Androida Engage Service Flag NIE jest ustawiona na wersję produkcyjną.
- Zainstaluj i otwórz aplikację Engage Verification.
- Jeśli wartość
isServiceAvailable
w aplikacji weryfikacyjnej tofalse
, kliknij przyciskToggle
w tej aplikacji, aby ustawić wartośćtrue
. - Wpisz nazwę pakietu aplikacji. Opublikowane dane zostaną wyświetlone automatycznie.
Otwórz aplikację i wykonaj te czynności:
- Zaloguj się.
- przełączać się między profilami (jeśli jest to obsługiwane);
- kupić nowy abonament,
- przejść na wyższą wersję subskrypcji,
- wygaśnięcie subskrypcji;
Weryfikowanie integracji
Aby przetestować integrację, użyj aplikacji weryfikacyjnej.
Aplikacja weryfikacyjna to aplikacja na Androida, której deweloperzy mogą używać do sprawdzania, czy integracja działa. Aplikacja zawiera funkcje, które pomagają programistom weryfikować dane i nadawać intencje. Pomaga to sprawdzić 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 w aplikacji do weryfikacji wszystko jest na zielono Jeśli wszystkie informacje o podmiocie są prawidłowe, przy wszystkich podmiotach pojawi się zielona ikona potwierdzenia „Wszystko w porządku”.
Rysunek 1. Subskrypcja została utworzona Problemy są też wyróżnione w aplikacji weryfikacyjnej
Rysunek 2. Nieudana subskrypcja Aby zobaczyć problemy w pakiecie subskrypcji, użyj pilota do telewizora, aby skupić się na konkretnym pakiecie subskrypcji, a następnie kliknij, aby wyświetlić problemy. Może być konieczne najpierw skupienie się na wierszu i przesunięcie w prawo, aby znaleźć kartę subskrypcji pakietowej. Problemy są oznaczone na czerwono, jak pokazano na rysunku 3. Użyj pilota, aby przewinąć w dół i zobaczyć problemy z uprawnieniami w ramach subskrypcji łączonej.
Rysunek 3. Błędy subskrypcji Aby zobaczyć problemy z uprawnieniem, użyj pilota do telewizora, aby skupić się na tym konkretnym uprawnieniu, a następnie kliknij, aby wyświetlić problemy. Problemy są wyróżnione na czerwono.
Rysunek 4. Szczegóły błędu subskrypcji
Pobierz
Przed pobraniem musisz zaakceptować poniższe warunki.