In diesem Leitfaden wird beschrieben, wie Entwickler mithilfe des Engage SDK App-Abo- und Berechtigungsdaten für Google TV freigeben. Nutzer können Inhalte finden, auf die sie Anspruch haben, und Google TV kann Nutzern direkt in Google TV auf dem Fernseher, Smartphone und Tablet relevante Inhaltsempfehlungen geben.
Voraussetzungen
Du musst den Feed mit den Media-Aktionen einrichten, bevor du die Device Entitlement API verwenden kannst. Führen Sie die Einrichtung des Feeds für Media-Aktionen durch, falls Sie dies noch nicht getan haben.
Vorarbeit
Führen Sie vor Beginn die folgenden Schritte aus: Vergewissern Sie sich, dass Ihre App für diese Integration auf API-Level 19 oder höher ausgerichtet ist.
Fügen Sie Ihrer App die
com.google.android.engage
-Bibliothek hinzu:Für die Integration gibt es separate SDKs: eines für mobile Apps und eines für TV-Apps.
Für Mobilgeräte
dependencies { implementation 'com.google.android.engage:engage-core:1.5.5 }
für TV
dependencies { implementation 'com.google.android.engage:engage-tv:1.0.2 }
Legen Sie in der Datei
AndroidManifest.xml
die Umgebung des Engage-Dienstes auf „Produktion“ fest.Für mobile apk
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
For TV apk
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
Legen Sie in der Datei „AndroidManifest.xml“ die Umgebung des Engage-Dienstes auf „Produktion“ fest, bevor Sie das APK an Google senden. Für eine optimale Leistung und zukünftige Kompatibilität sollten Daten nur veröffentlicht werden, wenn die App im Vordergrund ist und der Nutzer aktiv damit interagiert, z. B. beim Starten der App, nach der Anmeldung oder während der aktiven Nutzung. Wir raten davon ab, über Hintergrundprozesse zu veröffentlichen.
Veröffentliche Aboinformationen zu den folgenden Ereignissen:
- Der Nutzer meldet sich in Ihrer App an.
- Der Nutzer wechselt zwischen Profilen (falls Profile unterstützt werden).
- Der Nutzer kauft ein neues Abo.
- Der Nutzer rüstet ein bestehendes Abo auf.
- Das Abo des Nutzers läuft ab.
Integration
Dieser Abschnitt enthält die erforderlichen Codebeispiele und Anleitungen zum Implementieren von AccountProfile
und SubscriptionEntity
zum Verwalten verschiedener Abotypen.
Nutzerkonto und ‑profil
Wenn Sie personalisierte Funktionen auf Google TV nutzen möchten, müssen Sie Kontoinformationen angeben. Verwenden Sie AccountProfile
, um Folgendes anzugeben:
- Konto-ID: Eine eindeutige Kennung, die das Konto des Nutzers darstellt. Dies kann die tatsächliche Konto-ID oder eine entsprechend verschleierte Version sein.
// 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();
Abo mit gemeinsamer Stufe
Gib für Nutzer mit Basisabos bei Medienanbietern, z. B. bei einem Dienst mit einer Abostufe, die Zugriff auf alle kostenpflichtigen Inhalte gewährt, die folgenden wichtigen Details an:
Abotyp:Geben Sie den spezifischen Abotyp an, den 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 Probeabo.
Ablaufzeit:Optionale Zeit in Millisekunden. Geben Sie an, wann das Abo ablaufen soll.
Paketname des Anbieters:Geben Sie den Paketnamen der App an, die das Abo verwaltet.
Beispiel für den Feed des Beispiel-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 die App mehrstufige Premium-Abopakete anbietet, die erweiterte Inhalte oder Funktionen über die allgemeine Stufe hinaus umfassen, fügen Sie dem Abo eine oder mehrere Berechtigungen hinzu.
Diese Berechtigung hat die folgenden Felder:
- Kennung:Erforderlicher Kennungsstring für diese Berechtigung. Diese muss mit einer der Berechtigungs-IDs (nicht das ID-Feld) übereinstimmen, die im Feed des Medienanbieters, der auf Google TV veröffentlicht wurde, angegeben sind.
- Name:Diese Informationen dienen als Hilfsinformationen und werden für die Zuordnung von Berechtigungen verwendet. Der Name einer Berechtigung ist optional, aber ein visuell lesbarer Name erleichtert sowohl Entwicklern als auch Supportteams das Verständnis der Nutzerberechtigungen. Beispiel: Sling Orange.
- Expiration TimeMillis: Gib optional die Ablaufzeit in Millisekunden für diese Berechtigung an, falls sie von der Ablaufzeit des Abos abweicht. Standardmäßig läuft die Berechtigung mit Ablauf des Abos ab.
Für das folgende Beispiel-Snippet für einen Medienanbieter-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 abonnierten Nutzer 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 Dienstleistungspaket
Abos gehören in der Regel dem Medienanbieter der ursprünglichen App. Sie können einem verknüpften Dienstpaket zugewiesen werden, indem Sie den Namen des verknüpften Dienstpakets im Abo angeben.
Im folgenden Codebeispiel wird gezeigt, 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 untergeordneten Dienst hat, füge ein weiteres Abo hinzu und lege 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 für ein verknüpftes Dienstabo hinzufügen.
Abo-Set angeben
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.
Prüfen Sie mit isServiceAvailable
, ob der Dienst für die Integration verfügbar ist.
client.publishSubscription(
PublishSubscriptionRequest.Builder()
.setAccountProfile(accountProfile)
.setSubscription(subscription)
.build();
)
Verwende 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 neuesten Eintrag. Bei einem Fehler wird die gesamte Anfrage abgelehnt und der aktuelle Status bleibt erhalten.
Abo auf dem neuesten Stand halten
- Wenn du Nutzer bei Änderungen sofort informieren möchtest, ruf
publishSubscriptionCluster()
immer dann auf, wenn sich der Abostatus eines Nutzers ändert, z. B. bei Aktivierung, Deaktivierung, Upgrades oder Downgrades. Rufen Sie
publishSubscriptionCluster()
mindestens einmal pro Monat auf, um die Daten regelmäßig auf ihre Richtigkeit zu überprüfen.Wenn du die Daten zur Videosuche löschen möchtest, musst du die Daten eines Nutzers vor Ablauf der standardmäßigen Aufbewahrungsfrist von 60 Tagen manuell vom Google TV-Server löschen. Verwende dazu die Methode
client.deleteClusters()
. Dadurch werden alle vorhandenen Daten zur Videoauffindbarkeit für das Kontoprofil oder für das gesamte Konto gelöscht, je nach angegebenerDeleteReason
.Code-Snippet zum Entfernen des Nutzerabos
// 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() )
Testen
In diesem Abschnitt wird Schritt für Schritt beschrieben, wie du die Aboimplementierung testen kannst. Prüfen Sie vor der Einführung die Datenrichtigkeit und die ordnungsgemäße Funktion.
Checkliste für die Veröffentlichung einer Integration
Die Veröffentlichung sollte erfolgen, wenn die App im Vordergrund ist und der Nutzer aktiv damit interagiert.
Veröffentlichen, wenn:
- Der Nutzer meldet sich zum ersten Mal an.
- Der Nutzer ändert sein Profil (falls Profile unterstützt werden).
- Der Nutzer kauft ein neues Abo.
- Der Nutzer wechselt zu einem höheren Abo.
- Das Abo des Nutzers läuft ab.
Prüfen Sie, ob die App die
isServiceAvailable()
- undpublishClusters()
-APIs in Logcat bei den Veröffentlichungsereignissen korrekt aufruft.Prüfen Sie, ob die Daten in der Bestätigungs-App zu sehen sind. In der Bestätigungs-App sollte das Abo in einer separaten Zeile angezeigt werden. Wenn die Publish API aufgerufen wird, sollten die Daten in der Bestätigungs-App angezeigt werden.
- Prüfen Sie, ob das Engage Service-Flag in der Android-Manifestdatei der App NICHT auf „production“ festgelegt ist.
- Installieren und öffnen Sie die Engage Verification App.
- Wenn der Wert von
isServiceAvailable
in der Bestätigungs-Appfalse
ist, klicken Sie in der Bestätigungs-App auf die SchaltflächeToggle
, um ihn auftrue
festzulegen. - Geben Sie den Paketnamen der App ein. Die veröffentlichten Daten werden automatisch angezeigt.
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
- Das Abo ablaufen lassen.
Integration prüfen
Verwenden Sie die Bestätigungs-App, um Ihre Integration zu testen.
Die Bestätigungs-App ist eine Android-Anwendung, mit der Entwickler prüfen können, ob die Integration funktioniert. Die App bietet Funktionen, mit denen Entwickler Daten und Intents für die Übertragung prüfen können. So können Sie vor der Einführung die Richtigkeit der Daten und die ordnungsgemäße Funktionsweise überprüfen.
- 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 Sie, ob alle Status in der Bestätigungs-App grün sind. Wenn alle Informationen der Entität korrekt sind, wird bei allen Entitäten ein grünes Häkchen angezeigt.
Abbildung 1. Abo erfolgreich abgeschlossen Probleme werden auch in der Bestätigungs-App hervorgehoben
Abbildung 2: Abo fehlgeschlagen Wenn du die Probleme im Paketabo sehen möchtest, fokussiere dich mit der Fernbedienung auf das entsprechende Paketabo und klicke darauf, um die Probleme aufzurufen. Möglicherweise musst du zuerst den Fokus auf die Zeile legen und nach rechts gehen, um die Karte „Kombiniertes Abo“ zu finden. Die Probleme werden rot hervorgehoben, wie in Abbildung 3 dargestellt. Verwende die Fernbedienung, um nach unten zu scrollen und Probleme mit den Berechtigungen im Paketabo zu sehen.
Abbildung 3: Abofehler Wenn du die Probleme mit der Berechtigung sehen möchtest, fokussiere dich mit der TV-Fernbedienung auf die entsprechende Berechtigung und klicke darauf. Die Probleme werden rot hervorgehoben.
Abbildung 4: Details zum Abofehler