App-Berechtigungen mit Google TV über das Engage SDK teilen

Dieser Leitfaden enthält Anweisungen für Entwickler zum Teilen von App-Abo- und Berechtigungsdaten mit Google TV über das Engage SDK. Nutzer können Inhalte finden, auf die sie Zugriff haben, und Google TV aktivieren, um Nutzern direkt in Google TV-Umgebungen auf dem Fernseher, Smartphone und Tablet hochrelevante Inhaltsempfehlungen zu geben.

Vorbereitung

Bevor Sie die Device Entitlement API verwenden können, müssen Sie den Feed für Media Actions einbinden. Falls noch nicht geschehen, führen Sie den Einbindungsprozess für den Feed für Media Actions aus.

Vorarbeit

Führen Sie die Anweisungen unter „Vorarbeit“ im Startleitfaden aus.

  1. Veröffentlichen Sie Aboinformationen zu den folgenden Ereignissen:
    1. Nutzer meldet sich in Ihrer App an.
    2. Nutzer wechselt zwischen Profilen (falls Profile unterstützt werden).
    3. Nutzer erwirbt ein neues Abo.
    4. Nutzer führt ein Upgrade für ein bestehendes Abo durch.
    5. Abo des Nutzers läuft ab.

Integration

In diesem Abschnitt finden Sie die erforderlichen Codebeispiele und Anweisungen zum Implementieren von SubscriptionEntity zum Verwalten verschiedener Aboarten.

Abo der allgemeinen Stufe

Für Nutzer mit einfachen Abos für Dienste von Media-Anbietern, z. B. für einen Dienst mit einer Abostufe, die Zugriff auf alle kostenpflichtigen Inhalte gewährt, geben Sie diese wichtigen Details an:

  1. SubscriptionType: Geben Sie deutlich den spezifischen Aboplan an, den der Nutzer hat.

    • SUBSCRIPTION_TYPE_ACTIVE: Nutzer hat ein aktives kostenpflichtiges Abo.
    • SUBSCRIPTION_TYPE_ACTIVE_TRIAL: Nutzer hat ein Probeabo.
    • SUBSCRIPTION_TYPE_INACTIVE: Nutzer hat ein Konto, aber kein aktives Abo oder Probeabo.
  2. ExpirationTimeMillis: Optionale Zeit in Millisekunden. Geben Sie an, wann das Abo ablaufen soll.

  3. ProviderPackageName: Geben Sie den Paketnamen der App an, die das Abo verwaltet.

Beispiel für den Feed des Media-Anbieters.

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

Im folgenden Beispiel wird eine SubscriptionEntity für einen Nutzer erstellt:

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()

Premium-Abo

Wenn die App mehrstufige Premium-Abopakete anbietet, die erweiterte Inhalte oder Funktionen über die allgemeine Stufe hinaus enthalten, stellen Sie dies dar, indem Sie dem Abo eine oder mehrere Berechtigungen hinzufügen.

Diese Berechtigung hat die folgenden Felder:

  1. Identifier: Erforderlicher Kennzeichnungsstring für diese Berechtigung. Dieser muss mit einer der Berechtigungskennzeichnungen übereinstimmen (beachten Sie , dass dies nicht das Feld „ID“ ist), die im Feed des Media-Anbieters angegeben sind , der auf Google TV veröffentlicht wurde.
  2. Name: Dies sind Zusatzinformationen, die für den Abgleich von Berechtigungen verwendet werden. Obwohl optional, verbessert die Angabe eines für Menschen lesbaren Berechtigungsnamens das Verständnis der Nutzerberechtigungen sowohl für Entwickler als auch für Supportteams. Beispiel: Sling Orange.
  3. ExpirationTimeMillis: Geben Sie optional die Ablaufzeit in Millisekunden für diese Berechtigung an, wenn sie sich von der Ablaufzeit des Abos unterscheidet. Standardmäßig läuft die Berechtigung mit dem Ablauf des Abos ab.

Für das folgende Beispiel-Snippet des Media-Anbieterfeeds:

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

Im folgenden Beispiel wird eine SubscriptionEntity für einen Abonnenten erstellt:

// 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()

Abo für verknüpftes Dienstpaket

Abos gehören in der Regel zum Media-Anbieter der ursprünglichen App. Ein Abo kann jedoch einem verknüpften Dienstpaket zugeordnet werden, indem der Name des verknüpften Dienstpakets im Abo angegeben wird.

Das folgende Codebeispiel zeigt, wie ein Nutzerabo erstellt wird.

// 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()

Wenn der Nutzer außerdem ein weiteres Abo für einen Tochterdienst hat, fügen Sie ein weiteres Abo hinzu und legen Sie den Namen des verknüpften Dienstpakets entsprechend fest.

// 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()

Optional können Sie auch Berechtigungen zu einem Abo für einen verknüpften Dienst hinzufügen.

Aboset bereitstellen

Führen Sie den Job zum Veröffentlichen von Inhalten aus, während die App im Vordergrund ausgeführt wird.

Verwenden Sie die publishSubscriptionCluster() Methode aus der AppEngagePublishClient Klasse, um ein SubscriptionCluster Objekt zu veröffentlichen.

Achten Sie darauf, den Client zu initialisieren und die Verfügbarkeit des Dienstes zu prüfen, wie im Startleitfaden beschrieben.

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

Verwenden Sie setSubscription(), um zu prüfen, ob der Nutzer nur ein Abo für den Dienst haben sollte.

Verwenden Sie addLinkedSubscription() oder addLinkedSubscriptions(), die eine Liste verknüpfter Abos akzeptieren, damit der Nutzer null oder mehr verknüpfte Abos haben kann.

Wenn der Dienst die Anfrage erhält, wird ein neuer Eintrag erstellt und der alte Eintrag nach 60 Tagen automatisch gelöscht. Das System verwendet immer den neuesten Eintrag. Bei einem Fehler wird die gesamte Anfrage abgelehnt und der vorhandene Status beibehalten.

Abo auf dem neuesten Stand halten

  1. Wenn Sie sofortige Aktualisierungen bei Änderungen bereitstellen möchten, rufen Sie publishSubscriptionCluster auf, wenn sich der Abostatus eines Nutzers ändert, z. B. bei Aktivierung, Deaktivierung, Upgrades oder Downgrades.

  2. Um regelmäßig die Genauigkeit zu prüfen, rufen Sie publishSubscriptionCluster mindestens einmal pro Monat auf.

  3. Wenn Sie die Engage-Daten löschen möchten, löschen Sie die Daten eines Nutzers manuell vom Google TV-Server, bevor die standardmäßige Aufbewahrungsfrist von 60 Tagen abläuft. Verwenden Sie dazu die Methode client.deleteClusters. Dadurch werden alle vorhandenen Engage Daten für das Kontoprofil oder für das gesamte Konto gelöscht, je nach der angegebenen DeleteReason.

    Das folgende Code-Snippet zeigt, wie ein Nutzerabo entfernt wird:

    // 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()
      )
    

    Das folgende Code-Snippet zeigt, wie ein Nutzerabo entfernt wird, wenn der Nutzer die Einwilligung widerruft:

    // 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()
    )
    

    Der folgende Code zeigt, wie Abodaten beim Löschen eines Nutzerprofils entfernt werden.

    // 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()
    )
    

Test

In diesem Abschnitt finden Sie eine Schritt-für-Schritt-Anleitung zum Testen der Aboimplementierung. Prüfen Sie vor dem Launch die Datengenauigkeit und die ordnungsgemäße Funktion.

Checkliste für die Veröffentlichung der Integration

  1. Die Veröffentlichung sollte erfolgen, wenn die App im Vordergrund ausgeführt wird und der Nutzer aktiv mit ihr interagiert.

  2. Veröffentlichen Sie in den folgenden Fällen:

    • Nutzer meldet sich zum ersten Mal an.
    • Nutzer ändert das Profil (falls Profile unterstützt werden).
    • Nutzer erwirbt ein neues Abo.
    • Nutzer führt ein Upgrade für ein Abo durch.
    • Abo des Nutzers läuft ab.
  3. Prüfen Sie in logcat, ob die App die APIs isServiceAvailable und publishClusters bei den Veröffentlichungsereignissen korrekt aufruft.

  4. Prüfen Sie, ob die Daten in der Überprüfungs-App sichtbar sind. Das Abo sollte in der Überprüfungs-App als separate Zeile angezeigt werden. Wenn die Veröffentlichungs-API aufgerufen wird, sollten die Daten in der Überprüfungs-App angezeigt werden.

  5. Rufen Sie die App auf und führen Sie die folgenden Aktionen aus:

    • Melden Sie sich an.
    • Wechseln Sie zwischen Profilen (falls unterstützt).
    • Erwerben Sie ein neues Abo.
    • Führen Sie ein Upgrade für ein bestehendes Abo durch.
    • Lassen Sie das Abo ablaufen.

Integration verifizieren

Verwenden Sie die Überprüfungs-App, um Ihre Integration zu testen.

  1. Prüfen Sie für jedes Ereignis, ob die App die API publishSubscription aufgerufen hat. Prüfen Sie die veröffentlichten Daten in der Überprüfungs-App. Achten Sie darauf, dass in der Überprüfungs-App alles grün ist.
  2. Wenn alle Informationen zur Entität korrekt sind, wird in allen Entitäten ein grünes Häkchen „Alles in Ordnung“ angezeigt.

    Screenshot der Bestätigungs-App mit dem Hinweis, dass die Bestätigung erfolgreich war
    Abbildung 1. Erfolgreiches Abo
  3. Probleme werden auch in der Überprüfungs-App hervorgehoben.

    Screenshot des Fehlers in der Bestätigungs-App
    Abbildung 2: Abo nicht erfolgreich
  4. Wenn Sie die Probleme im gebündelten Abo sehen möchten, verwenden Sie die TV-Fernbedienung, um den Fokus auf dieses bestimmte gebündelte Abo zu legen, und klicken Sie, um die Probleme aufzurufen. Möglicherweise müssen Sie zuerst den Fokus auf die Zeile legen und nach rechts wechseln, um die Karte „Gebündeltes Abo“ zu finden. Die Probleme werden rot hervorgehoben, wie in Abbildung 3 dargestellt. Verwenden Sie außerdem die Fernbedienung, um nach unten zu scrollen und Probleme in den Berechtigungen innerhalb des gebündelten Abos zu sehen.

    Screenshot mit Fehlerdetails der Bestätigungs-App
    Abbildung 3 : Abo-Fehler
  5. Wenn Sie die Probleme in der Berechtigung sehen möchten, verwenden Sie die TV-Fernbedienung, um den Fokus auf diese bestimmte Berechtigung zu legen, und klicken Sie, um die Probleme aufzurufen. Die Probleme werden rot hervorgehoben.

    Screenshot des Fehlers in der Bestätigungs-App
    Abbildung 4: Details zu Abo-Fehlern