Partager les droits d'accès des applications avec Google TV à l'aide du SDK Engage

Ce guide explique aux développeurs comment partager les données d'abonnement et d'accès des applications avec Google TV à l'aide du SDK Engage. Les utilisateurs peuvent trouver les contenus auxquels ils ont droit et autoriser Google TV à leur proposer des recommandations de contenus très pertinentes, directement dans les expériences Google TV sur téléviseur, mobile et tablette.

Prérequis

Vous devez intégrer le flux d'actions multimédias avant de pouvoir utiliser l'API d'autorisations d'appareil. Si vous ne l'avez pas déjà fait, suivez le processus d'intégration du flux d'actions multimédias.

Travail préalable

Avant de commencer, procédez comme suit : vérifiez que votre application cible le niveau d'API 19 ou supérieur pour cette intégration.

  1. Ajoutez la bibliothèque com.google.android.engage à votre application :

    Des SDK distincts doivent être utilisés pour l'intégration: un pour les applications mobiles et un pour les applications TV.

    Pour mobile

    
      dependencies {
        implementation 'com.google.android.engage:engage-core:1.5.5
      }
    

    pour TV

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.2
      }
    
  2. Définissez l'environnement de service Engage sur "production" dans le fichier AndroidManifest.xml.

    Pour l'APK mobile

    
    <meta-data
          android:name="com.google.android.engage.service.ENV"
          android:value="PRODUCTION">
    </meta-data>
    

    APK pour la TV

    
    <meta-data
        android:name="com.google.android.engage.service.ENV"
        android:value="PRODUCTION">
    </meta-data>
    
  3. Avant d'envoyer l'APK à Google, définissez l'environnement de service Engage sur "production" dans votre fichier AndroidManifest.xml. Pour des performances optimales et une compatibilité future, ne publiez les données que lorsque l'application est au premier plan et que l'utilisateur interagit activement avec elle, par exemple au lancement de l'application, après la connexion ou lors d'une utilisation active. La publication à partir de processus en arrière-plan est déconseillée.

  4. Publiez des informations sur l'abonnement pour les événements suivants:

    1. L'utilisateur se connecte à votre application.
    2. L'utilisateur passe d'un profil à un autre (si les profils sont compatibles).
    3. L'utilisateur souscrit un nouvel abonnement.
    4. L'utilisateur passe à un forfait supérieur.
    5. L'abonnement de l'utilisateur expire.

Intégration

Cette section fournit les exemples de code et les instructions nécessaires pour implémenter AccountProfile et SubscriptionEntity afin de gérer différents types d'abonnements.

Compte et profil utilisateur

Pour autoriser les fonctionnalités personnalisées sur Google TV, fournissez des informations de compte. Utilisez AccountProfile pour fournir:

  1. ID de compte: identifiant unique représentant le compte de l'utilisateur. Il peut s'agir de l'ID de compte réel ou d'une version masquée de manière appropriée.
// 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();

Abonnement de niveau standard

Pour les utilisateurs disposant d'abonnements de base aux services de fournisseurs de contenus multimédias (par exemple, un service proposant un seul niveau d'abonnement qui donne accès à tous les contenus payants), fournissez les informations essentielles suivantes:

  1. Type d'abonnement:indiquez clairement le forfait d'abonnement spécifique dont dispose l'utilisateur.

    1. SUBSCRIPTION_TYPE_ACTIVE: l'utilisateur dispose d'un abonnement payant actif.
    2. SUBSCRIPTION_TYPE_ACTIVE_TRIAL: l'utilisateur dispose d'un abonnement d'essai.
    3. SUBSCRIPTION_TYPE_INACTIVE: l'utilisateur dispose d'un compte, mais aucun abonnement ni essai n'est actif.
  2. Expiration time (Délai d'expiration) : durée facultative, en millisecondes. Indiquez la date d'expiration de l'abonnement.

  3. Nom du package du fournisseur:spécifiez le nom du package de l'application qui gère l'abonnement.

Exemple pour le flux de l'exemple de fournisseur multimédia

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

L'exemple suivant crée un SubscriptionEntity pour un utilisateur:

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

Abonnement Premium

Si l'application propose des packages d'abonnement premium à plusieurs niveaux, qui incluent du contenu ou des fonctionnalités étendus au-delà du niveau commun, indiquez-le en ajoutant un ou plusieurs droits d'accès à "Abonnement".

Ce droit d'accès comporte les champs suivants:

  1. Identifiant:chaîne d'identifiant requise pour ce droit d'accès. Il doit correspondre à l'un des identifiants d'éligibilité (notez qu'il ne s'agit pas du champ d'ID) fournis dans le flux du fournisseur de contenu multimédia publié sur Google TV.
  2. Nom:il s'agit d'informations auxiliaires utilisées pour la mise en correspondance des droits d'accès. Bien que facultatif, fournir un nom de droit d'accès lisible par l'utilisateur permet de mieux comprendre les droits d'accès des utilisateurs, à la fois pour les développeurs et les équipes d'assistance. Exemple: Sling Orange
  3. Expiration TimeMillis: vous pouvez spécifier le délai d'expiration en millisecondes pour ce droit d'accès, s'il diffère du délai d'expiration de l'abonnement. Par défaut, le droit d'accès expire à la fin de l'abonnement.

Pour l'extrait de flux de fournisseur multimédia suivant:

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

L'exemple suivant crée un SubscriptionEntity pour un utilisateur abonné:

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

Abonnement au package de services associé

Bien que les abonnements appartiennent généralement au fournisseur multimédia de l'application d'origine, un abonnement peut être attribué à un package de services associé en spécifiant le nom du package de services associé dans l'abonnement.

L'exemple de code suivant montre comment créer un abonnement utilisateur.

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

De plus, si l'utilisateur dispose d'un autre abonnement à un service affilié, ajoutez un autre abonnement et définissez le nom du package de service associé en conséquence.

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

Vous pouvez également ajouter des droits d'accès à un abonnement de service associé.

Fournir un ensemble d'abonnements

Exécutez la tâche de publication du contenu lorsque l'application est au premier plan.

Utilisez la méthode publishSubscriptionCluster() de la classe AppEngagePublishClient pour publier un objet SubscriptionCluster.

Utilisez isServiceAvailable pour vérifier si le service est disponible pour l'intégration.

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

Utilisez setSubscription() pour vérifier que l'utilisateur ne doit avoir qu'un seul abonnement au service.

Utilisez addLinkedSubscription() ou addLinkedSubscriptions(), qui acceptent une liste d'abonnements associés, pour permettre à l'utilisateur d'avoir zéro ou plusieurs abonnements associés.

Lorsque le service reçoit la requête, une nouvelle entrée est créée et l'ancienne est automatiquement supprimée au bout de 60 jours. Le système utilise toujours la dernière entrée. En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.

Maintenir l'abonnement à jour

  1. Pour fournir des mises à jour immédiates en cas de modification, appelez publishSubscriptionCluster() chaque fois que l'état de l'abonnement d'un utilisateur change, par exemple en cas d'activation, de désactivation, de mise à niveau ou de rétrogradation.
  2. Pour valider régulièrement la précision, appelez publishSubscriptionCluster() au moins une fois par mois.

  3. Pour supprimer les données de découverte de vidéos, supprimez manuellement les données d'un utilisateur du serveur Google TV avant la période de conservation standard de 60 jours. Pour ce faire, utilisez la méthode client.deleteClusters(). Toutes les données de découverte de vidéos existantes sont supprimées pour le profil du compte ou pour l'ensemble du compte, en fonction de l'DeleteReason donné.

    Extrait de code permettant de supprimer l'abonnement de l'utilisateur

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

Tests

Cette section fournit un guide par étapes pour tester l'implémentation des abonnements. Vérifiez l'exactitude des données et le bon fonctionnement de la fonctionnalité avant de la lancer.

Checklist de publication de l'intégration

  1. La publication doit se produire lorsque l'application est au premier plan et que l'utilisateur interagit activement avec elle.

  2. Publier quand:

    • L'utilisateur se connecte pour la première fois.
    • L'utilisateur change de profil (si les profils sont acceptés).
    • L'utilisateur souscrit un nouvel abonnement.
    • L'utilisateur passe à un abonnement supérieur.
    • L'abonnement de l'utilisateur expire.
  3. Vérifiez si l'application appelle correctement les API isServiceAvailable() et publishClusters() dans Logcat, sur les événements de publication.

  4. Vérifiez que les données sont visibles dans l'application de validation. L'application de validation doit afficher l'abonnement sur une ligne distincte. Lorsque l'API de publication est appelée, les données doivent s'afficher dans l'application de validation.

    • Vérifiez que l'indicateur de service Engage n'est PAS défini sur "production" dans le fichier manifeste Android de l'application.
    • Installez et ouvrez l'application Engage Verification.
    • Si la valeur de isServiceAvailable est false dans l'application de validation, cliquez sur le bouton Toggle dans l'application de validation pour la définir sur true.
    • Saisissez le nom du package de l'application. Les données publiées s'affichent automatiquement.
  5. Accédez à l'application et effectuez chacune des actions suivantes:

    • Connectez-vous.
    • changer de profil (si cette fonctionnalité est disponible).
    • Souscrire un nouvel abonnement
    • Mettre à niveau un abonnement existant.
    • Expiration de l'abonnement.

Vérifier l'intégration

Pour tester votre intégration, utilisez l'application de validation.

L'application de validation est une application Android que les développeurs peuvent utiliser pour vérifier que l'intégration fonctionne. Elle comprend des fonctionnalités permettant aux développeurs de valider des données et de diffuser des intents. Il permet de vérifier l'exactitude des données et le bon fonctionnement avant le lancement.

  1. Pour chacun des événements, vérifiez si l'application a appelé l'API publishSubscription. Vérifiez les données publiées dans l'application de validation. Vérifiez que tout est vert dans l'application de validation
  2. Si toutes les informations de l'entité sont correctes, une coche verte "OK" s'affiche dans toutes les entités.

    Capture d&#39;écran de validation de l&#39;application
    Figure 1. Abonnement souscrit
  3. Les problèmes sont également mis en évidence dans l'application de validation.

    Capture d&#39;écran de l&#39;erreur de l&#39;application de validation
    Figure 2 : Abonnement non abouti
  4. Pour afficher les problèmes liés à l'abonnement groupé, utilisez la télécommande du téléviseur pour vous concentrer sur cet abonnement groupé spécifique, puis cliquez pour afficher les problèmes. Vous devrez peut-être d'abord placer le focus sur la ligne et vous déplacer vers la droite pour trouver la fiche d'abonnement groupé. Les problèmes sont mis en évidence en rouge, comme illustré à la figure 3. Utilisez également la télécommande pour faire défiler l'écran vers le bas afin d'afficher les problèmes liés aux droits d'accès dans l'abonnement groupé.

    Capture d&#39;écran des détails de l&#39;erreur de validation de l&#39;application
    Figure 3 : Erreurs d'abonnement
  5. Pour afficher les problèmes liés au droit d'accès, utilisez la télécommande du téléviseur pour vous concentrer sur ce droit d'accès spécifique, puis cliquez pour afficher les problèmes. Les problèmes sont mis en surbrillance en rouge.

    Capture d&#39;écran de l&#39;erreur de l&#39;application de validation
    Figure 4.Détails de l'erreur d'abonnement