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

book_path: /distribute/other-docs/_book.yaml project_path: /distribute/other-docs/_project.yaml

In diesem Leitfaden finden Entwickler eine Anleitung dazu, wie sie mit dem Engage SDK Daten zu App-Abos und Berechtigungen mit Google TV teilen können. Nutzer können Inhalte finden, auf die sie Anspruch haben, und Google TV aktivieren, um hochrelevante Inhaltsempfehlungen direkt in Google TV auf Fernsehern, Smartphones und Tablets zu erhalten.

Voraussetzungen

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

Vorbereitung

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

  1. Aboinformationen für die folgenden Ereignisse veröffentlichen:
    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.

Abo der gemeinsamen Stufe

Für Nutzer mit Basisabonnements 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: Geben Sie 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 des Medienanbieters

"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 über die übliche Stufe hinaus erweiterte Inhalte oder Funktionen enthalten, können Sie dies darstellen, indem Sie dem Abo ein oder mehrere Berechtigungen hinzufügen.

Diese Berechtigung hat die folgenden Felder:

  1. Identifier: Erforderlicher Kennzeichnungsstring für diese Berechtigung. Diese muss mit einer der Berechtigungs-IDs übereinstimmen (Hinweis: Dies ist nicht das ID-Feld), die im Feed des Medienanbieters für Google TV veröffentlicht wurden.
  2. Name: Diese Zusatzinformationen werden für den Abgleich von Berechtigungen verwendet. Die Angabe eines für Menschen 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 Media-Anbieter der ursprünglichen App. Ein Abo kann jedoch einem verknüpften Servicepaket zugeordnet werden, indem der Name des verknüpften Servicepakets 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() aus 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.

Verwenden Sie 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 überprüfen, rufen Sie publishSubscriptionCluster mindestens einmal pro Monat auf.

  3. Wenn Sie die Daten zur Videoermittlung 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 Daten zur Videoermittlung 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 video discovery 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 video discovery 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 video discovery data.
    client.deleteClusters(
      new DeleteClustersRequest.Builder()
      .setAccountProfile(accountProfile)
      .setReason(DeleteReason.DELETE_REASON_ACCOUNT_PROFILE_DELETION)
      .build()
    )
    

Testen

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 Funktionalität.

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 ändert 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 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 läuft ab.

Integration prüfen

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

  1. Prüfen Sie für jedes Ereignis, ob die App die publishSubscription-API aufgerufen hat. Prüfen Sie die veröffentlichten Daten in der Bestätigungs-App. Prüfen, 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 der Bestätigungs-App mit Erfolgsmeldung
    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: Abofehler
  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.Details zum Abo-Fehler