Udostępnianie uprawnień do aplikacji w Google TV za pomocą pakietu Engage SDK

Ten przewodnik zawiera instrukcje dla deweloperów dotyczące udostępniania danych o subskrypcjach i uprawnieniach w aplikacji Google TV za pomocą pakietu Engage SDK. Użytkownicy mogą znajdować treści, do których mają uprawnienia, i włączyć Google TV, aby otrzymywać wysoce 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 wdrożyć plik danych działań multimedialnych. Jeśli jeszcze tego nie zrobisz, dokończ proces wdrażania pliku danych działań multimedialnych.

Przygotowanie

Wykonaj instrukcje przygotowania opisane w Przewodniku dla początkujących.

  1. Opublikuj informacje o subskrypcji w przypadku tych zdarzeń:
    1. Użytkownik loguje się w Twojej aplikacji.
    2. Użytkownik przełącza się między profilami (jeśli są obsługiwane).
    3. Użytkownik kupuje nową subskrypcję.
    4. Użytkownik przechodzi na wyższą subskrypcję.
    5. Subskrypcja użytkownika wygasa.

Integracja

W tej sekcji znajdziesz niezbędne przykłady kodu i instrukcje dotyczące implementowania SubscriptionEntity do zarządzania różnymi typami subskrypcji.

Subskrypcja na poziomie podstawowym

W przypadku użytkowników z podstawowymi subskrypcjami usług dostawcy treści multimedialnych, np. usługi, która ma 1 poziom subskrypcji zapewniający dostęp do wszystkich płatnych treści, podaj te podstawowe informacje:

  1. SubscriptionType: wyraźnie wskaż konkretny plan subskrypcji, 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.
  2. ExpirationTimeMillis: opcjonalny czas w milisekundach. Określ, kiedy subskrypcja ma wygasnąć.

  3. ProviderPackageName: określ nazwę pakietu aplikacji, która obsługuje subskrypcję.

Przykład dla przykładowego pliku danych dostawcy treści multimedialnych.

"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
  }

Ten przykład tworzy 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, dodaj do subskrypcji co najmniej 1 uprawnienie.

To uprawnienie ma te pola:

  1. Identifier: wymagany ciąg znaków identyfikatora tego uprawnienia. Musi on być zgodny z jednym z identyfikatorów uprawnień (pamiętaj, że nie jest to pole ID) podanych w pliku danych dostawcy treści multimedialnych opublikowanym w Google TV.
  2. Name: to informacje pomocnicze, które służą do dopasowywania uprawnień. Podanie nazwy uprawnienia w sposób zrozumiały dla człowieka jest opcjonalne, ale ułatwia deweloperom i zespołom pomocy zrozumienie uprawnień użytkowników. Przykład: Sling Orange.
  3. ExpirationTimeMillis: opcjonalnie określ czas wygaśnięcia tego uprawnienia w milisekundach, jeśli różni się on od czasu wygaśnięcia subskrypcji. Domyślnie uprawnienie wygaśnie wraz z wygaśnięciem subskrypcji.

W przypadku tego przykładowego fragmentu pliku danych dostawcy treści multimedialnych:

"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"
  }

Ten przykład tworzy SubscriptionEntity dla subskrybenta:

// 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łączonej usługi

Subskrypcje należą zwykle do dostawcy treści multimedialnych aplikacji, z której pochodzą, ale można je przypisać do pakietu połączonej usługi, określając nazwę tego pakietu w subskrypcji.

Ten 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 zależnej, 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 subskrypcji połączonej 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.

Pamiętaj, aby zainicjować klienta i sprawdzić dostępność usługi zgodnie z opisem w Przewodniku dla początkujących.

client.publishSubscription(
  PublishSubscriptionRequest.Builder()
    .setAccountProfile(accountProfile)
    .setSubscription(subscription)
    .build()
  )

Aby sprawdzić, czy użytkownik powinien mieć tylko 1 subskrypcję usługi, użyj metody setSubscription().

Aby umożliwić użytkownikowi korzystanie z co najmniej 1 połączonej subskrypcji, użyj metody addLinkedSubscription() lub addLinkedSubscriptions(), która akceptuje listę połączonych subskrypcji.

Gdy usługa otrzyma prośbę, zostanie utworzony 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 zostanie odrzucona, a dotychczasowy stan zostanie zachowany.

Aktualizowanie subskrypcji

  1. Aby natychmiast udostępniać aktualizacje po zmianach, wywołuj metodę publishSubscriptionCluster za każdym razem, gdy zmieni się stan subskrypcji użytkownika, np. aktywacja, dezaktywacja, przejście na wyższy lub niższy poziom.

  2. Aby regularnie sprawdzać poprawność danych, wywołuj metodę publishSubscriptionCluster co najmniej raz w miesiącu.

  3. Aby usunąć dane Engage, przed upływem standardowego 60-dniowego okresu przechowywania ręcznie usuń dane użytkownika z serwera Google TV za pomocą metody client.deleteClusters. Spowoduje to usunięcie wszystkich dotychczasowych danych Engage dotyczących profilu konta lub całego konta w zależności od podanego DeleteReason.

    Ten fragment kodu pokazuje, jak usunąć subskrypcję użytkownika:

    // If the user logs out from your media app, you must make the following call
    // to remove subscription and other Engage data from the current
    // google TV device.
    client.deleteClusters(
      new DeleteClustersRequest.Builder()
        .setAccountProfile(accountProfile)
      .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
      .build()
      )
    

    Ten fragment kodu pokazuje, jak usunąć subskrypcję użytkownika, gdy ten wycofa zgodę:

    // If the user revokes the consent to share across device, make the call
    // to remove subscription and other Engage data from all google
    // TV devices.
    client.deleteClusters(
      new DeleteClustersRequest.Builder()
        .setAccountProfile(accountProfile)
        .setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT)
        .build()
    )
    

    Ten kod pokazuje, jak usunąć dane subskrypcji po usunięciu profilu użytkownika:

    // If the user delete a specific profile, you must make the following call
    // to remove subscription data and other Engage data.
    client.deleteClusters(
      new DeleteClustersRequest.Builder()
      .setAccountProfile(accountProfile)
      .setReason(DeleteReason.DELETE_REASON_ACCOUNT_PROFILE_DELETION)
      .build()
    )
    

Testowanie

W tej sekcji znajdziesz szczegółowe instrukcje dotyczące testowania implementacji subskrypcji. Przed uruchomieniem sprawdź dokładność danych i prawidłowe działanie.

Lista kontrolna publikowania integracji

  1. Publikowanie powinno odbywać się, gdy aplikacja działa na pierwszym planie, a użytkownik aktywnie z niej korzysta.

  2. Publikuj, gdy:

    • użytkownik loguje się po raz pierwszy;
    • użytkownik zmienia profil (jeśli są obsługiwane);
    • użytkownik kupuje nową subskrypcję;
    • użytkownik przechodzi na wyższą subskrypcję;
    • subskrypcja użytkownika wygasa.
  3. Sprawdź, czy aplikacja prawidłowo wywołuje interfejsy API isServiceAvailable() i publishClusters() w logcat w przypadku zdarzeń publikowania.

  4. Sprawdź, czy dane są widoczne w aplikacji weryfikacyjnej. Aplikacja weryfikacyjna powinna wyświetlać subskrypcję jako osobny wiersz. Gdy zostanie wywołany interfejs API publikowania, dane powinny pojawić się w aplikacji weryfikacyjnej.

  5. Otwórz aplikację i wykonaj każdą z tych czynności:

    • Zaloguj się.
    • Przełącz się między profilami (jeśli są obsługiwane).
    • Kup nową subskrypcję.
    • Przejdź na wyższą subskrypcję.
    • Spowoduj wygaśnięcie subskrypcji.

Sprawdź integrację

Aby przetestować integrację, użyj aplikacji weryfikacyjnej.

  1. W przypadku każdego zdarzenia sprawdź, czy aplikacja wywołała interfejs API publishSubscription. Sprawdź opublikowane dane w aplikacji weryfikacyjnej. Upewnij się, że w aplikacji weryfikacyjnej wszystko jest na zielono.
  2. Jeśli wszystkie informacje o encji są prawidłowe, we wszystkich encjach wyświetli się zielony znacznik „Wszystko w porządku”.

    Zrzut ekranu z informacją o pomyślnej weryfikacji w aplikacji weryfikacyjnej
    Rysunek 1. Subskrypcja zakończona powodzeniem
  3. Problemy są też wyróżnione w aplikacji weryfikacyjnej.

    Zrzut ekranu z błędem aplikacji do weryfikacji
    Rysunek 2.Subskrypcja nieudana
  4. Aby zobaczyć problemy z subskrypcją w pakiecie, użyj pilota do telewizora, aby skupić się na tej konkretnej subskrypcji w pakiecie, i kliknij, aby zobaczyć problemy. Może być konieczne najpierw skupienie się na wierszu i przesunięcie w prawo, aby znaleźć kartę Subskrypcja w pakiecie. Problemy są wyróżnione na czerwono, jak pokazano na rysunku 3. Użyj też pilota, aby przewinąć w dół i zobaczyć problemy z uprawnieniami w subskrypcji w pakiecie.

    Zrzut ekranu ze szczegółami błędu aplikacji do weryfikacji
    Rysunek 3.Błędy subskrypcji
  5. Aby zobaczyć problemy z uprawnieniem, użyj pilota do telewizora, aby skupić się na tym konkretnym uprawnieniu, i kliknij, aby zobaczyć problemy. Problemy są wyróżnione na czerwono.

    Zrzut ekranu z błędem aplikacji do weryfikacji
    Rysunek 4.Szczegóły błędu subskrypcji