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

In dieser Anleitung erfahren Entwickler, wie sie mit dem Engage SDK Daten zu App-Abos und Berechtigungen für Google TV freigeben können. Nutzer können so Inhalte finden, auf die sie Zugriff haben, und Google TV kann Nutzern direkt in Google TV-Umgebungen auf Fernsehern, Smartphones und Tablets hochrelevante Inhaltsempfehlungen geben.

Vorbereitung

Sie müssen den Media Actions-Feed einrichten, bevor Sie die Device Entitlement API verwenden können. Falls noch nicht geschehen, führen Sie die Einrichtung des Feeds für Media-Aktionen durch.

Vorarbeit

Führen Sie die Schritte im Startleitfaden unter Vorbereitung aus.

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

Integration

In diesem Abschnitt finden Sie die erforderlichen Codebeispiele und Anleitungen für die Implementierung von SubscriptionEntity zur Verwaltung verschiedener Abotypen.

Gemeinsames Abo

Für Nutzer mit Basisabos für Dienste von Medienanbietern, z. B. ein Dienst mit einer Abo-Stufe, die Zugriff auf alle kostenpflichtigen Inhalte gewährt, geben Sie diese wichtigen Details an:

  1. SubscriptionType: Gib deutlich an, welches Abo der Nutzer hat.

    • SUBSCRIPTION_TYPE_ACTIVE: Der Nutzer hat ein aktives kostenpflichtiges Abo.
    • SUBSCRIPTION_TYPE_ACTIVE_TRIAL: Der Nutzer hat ein Probeabo.
    • SUBSCRIPTION_TYPE_INACTIVE: Der Nutzer hat ein Konto, aber kein aktives Abo oder keinen aktiven Testzeitraum.
  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 Beispielfeed für Medienanbieter

"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 ein 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 Ihre App mehrstufige Premium-Abopakete anbietet, die erweiterte Inhalte oder Funktionen über die gemeinsame Stufe hinaus enthalten, fügen Sie dem Abo ein oder mehrere Berechtigungen hinzu, um dies darzustellen.

Dieser Anspruch hat die folgenden Felder:

  1. Identifier: Erforderlicher Kennzeichnungsstring für diese Berechtigung. Dieser Wert muss mit einer der Berechtigungs-IDs übereinstimmen, die im Feed des Medienanbieters für Google TV veröffentlicht wurden. Beachten Sie, dass dies nicht das ID-Feld ist.
  2. Name: Diese Zusatzinformationen werden für den Abgleich von Berechtigungen verwendet. Die Angabe eines lesbaren Berechtigungsnamens ist zwar optional, verbessert aber das Verständnis der Nutzerberechtigungen sowohl für Entwickler als auch für Supportteams. Beispiel: Sling Orange
  3. ExpirationTimeMillis: Optional können Sie die Ablaufzeit in Millisekunden für diese Berechtigung angeben, 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 für einen Media-Anbieter-Feed:

"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 ein 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 Medienanbieter 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 Sie ein Nutzer-Abo erstellen.

// 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 untergeordneten Dienst 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 einem Abo für einen verknüpften Dienst auch Berechtigungen hinzufügen.

Abo-Set bereitstellen

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

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

Achten Sie darauf, den Client zu initialisieren und die Dienstverfügbarkeit 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.

Verwende addLinkedSubscription() oder addLinkedSubscriptions(), die eine Liste verknüpfter Abos akzeptieren, damit Nutzer null oder mehr verknüpfte Abos haben können.

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

Abo auf dem neuesten Stand halten

  1. Um sofortige Aktualisierungen bei Änderungen zu ermöglichen, rufen Sie publishSubscriptionCluster auf, wenn sich der Abostatus eines Nutzers ändert, z. B. bei Aktivierung, Deaktivierung, Upgrades oder Downgrades.

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

  3. Wenn Sie die Engage-Daten vor dem standardmäßigen Aufbewahrungszeitraum von 60 Tagen löschen möchten, müssen Sie die Daten eines Nutzers manuell vom Google TV-Server löschen. 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 angegebener 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 das 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 Implementierung von Abos. Prüfen Sie vor dem Launch die Richtigkeit der Daten und die ordnungsgemäße Funktion.

Checkliste für die Veröffentlichung von Integrationen

  1. Die Veröffentlichung sollte erfolgen, wenn sich die App im Vordergrund befindet und der Nutzer aktiv mit ihr interagiert.

  2. Veröffentlichen, wenn:

    • Der Nutzer meldet sich zum ersten Mal an.
    • Der Nutzer wechselt das Profil (falls Profile unterstützt werden).
    • Der Nutzer kauft ein neues Abo.
    • Der Nutzer führt ein Abo-Upgrade durch.
    • Das Nutzerabo läuft ab.
  3. Prüfen Sie im Logcat, ob die App die APIs isServiceAvailable() und publishClusters() bei der Veröffentlichung von Ereignissen korrekt aufruft.

  4. Prüfen Sie, ob die Daten in der Bestätigungs-App angezeigt werden. Das Abo sollte in der Bestätigungs-App als separate Zeile angezeigt werden. Wenn die Publish API aufgerufen wird, sollten die Daten in der Bestätigungs-App angezeigt werden.

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

    • Melden Sie sich an.
    • Zwischen Profilen wechseln (falls unterstützt).
    • Schließen Sie ein neues Abo ab.
    • Ein bestehendes Abo upgraden
    • Abo ablaufen lassen

Integration verifizieren

Verwenden Sie zum Testen Ihrer Integration die Bestätigungs-App.

  1. Prüfen Sie für jedes Ereignis, ob die publishSubscription API von der App aufgerufen wurde. Überprüfen Sie die veröffentlichten Daten in der Bestätigungs-App. Prüfen Sie, ob in der Bestätigungs-App alles grün ist.
  2. Wenn alle Informationen der Entität korrekt sind, wird bei allen Entitäten ein grünes Häkchen mit dem Hinweis „Alles in Ordnung“ angezeigt.

    Screenshot: Bestätigungs-App erfolgreich
    Abbildung 1. Erfolgreiches Abo
  3. Probleme werden auch in der Bestätigungs-App hervorgehoben.

    Screenshot des Fehlers in der Bestätigungs-App
    Abbildung 2.Abo fehlgeschlagen
  4. Wenn du die Probleme im Abo mit Zusatzleistungen sehen möchtest, verwende die TV-Fernbedienung, um den Fokus auf dieses Abo zu legen, und klicke dann, um die Probleme aufzurufen. Möglicherweise müssen Sie zuerst den Fokus auf die Zeile legen und dann nach rechts bewegen, um die Karte für das gebündelte Abo zu finden. Die Probleme sind rot hervorgehoben (siehe Abbildung 3). Verwende die Fernbedienung, um nach unten zu scrollen und Probleme mit den Berechtigungen im Abo mit Zusatzleistungen zu sehen.

    Screenshot mit Fehlerdetails der Bestätigungs-App
    Abbildung 3: Abo-Fehler
  5. Wenn du die Probleme mit der Berechtigung sehen möchtest, verwende die TV-Fernbedienung, um den Fokus auf die entsprechende Berechtigung zu legen, und klicke, um die Probleme aufzurufen. Die Probleme werden rot hervorgehoben.

    Screenshot des Fehlers in der Bestätigungs-App
    Abbildung 4: Abo-Fehlerdetails