Google est en train de développer une surface sur appareil, qui organisera les applications des utilisateurs par secteurs et offrira une nouvelle expérience immersive permettant une consommation et une découverte personnalisées du contenu de ces applications. Cette expérience plein écran donnera aux développeurs partenaires la possibilité de présenter leurs meilleurs contenus enrichis sur une chaîne dédiée en dehors de leur application.
Ce guide explique aux développeurs partenaires comment intégrer leur contenu vidéo à l'aide du SDK Engage dans le but de pouvoir renseigner cette nouvelle surface et les surfaces Google existantes.
Détails de l'intégration
Terminologie
Cette intégration comprend les trois types de clusters suivants : Recommendation (Recommandations), Continuation (Suite) et Featured (Sélection).
Les clusters Recommendation affichent des suggestions personnalisées de contenus à regarder provenant d'un développeur partenaire individuel.
Les recommandations présentent la structure suivante :
Cluster "Recommendation" : vue de l'interface utilisateur contenant un groupe de recommandations du même développeur partenaire.
Entité : objet représentant un seul élément dans un cluster. Une entité peut être un film, une émission télévisée, une série TV, une vidéo en direct, etc. Consultez la section Fournir les données d'entité pour obtenir la liste des types d'entités acceptés.
Le cluster Continuation affiche des vidéos inachevées et des nouveaux épisodes pertinents de plusieurs développeurs partenaires dans un même groupe d'UI. Chaque développeur partenaire est autorisé à diffuser au maximum 10 entités dans le cluster "Continuation". Des études ont révélé que les recommandations personnalisées, ainsi que les contenus qui entrent dans la catégorie "Continuation", génèrent un engagement optimal des utilisateurs.
Le cluster Featured affiche une sélection d'entités de plusieurs développeurs partenaires dans un même groupe d'UI. Il n'existe qu'un seul cluster "Featured", situé dans la partie supérieure de l'UI avec un emplacement prioritaire au-dessus de tous les clusters "Recommendation". Chaque développeur partenaire est autorisé à diffuser jusqu'à 10 entités dans le cluster "Featured".
Travail préalable
Niveau d'API minimal : 19
Ajoutez la bibliothèque com.google.android.engage:engage-core
à votre application :
dependencies {
// Make sure you also include that repository in your project's build.gradle file.
implementation 'com.google.android.engage:engage-core:1.5.2'
}
Pour en savoir plus, consultez la page Visibilité des packages sous Android 11.
Résumé
La conception repose sur l'implémentation d'un service lié.
Les données qu'un client peut publier sont soumises aux limites suivantes pour chaque type de cluster :
Type de cluster | Nombre limite de clusters | Limites maximales d'entités dans un cluster |
---|---|---|
Cluster(s) "Recommendation" | 5 maximum | 50 maximum |
Cluster "Continuation" | 1 maximum | 10 maximum |
Cluster "Featured" | 1 maximum | 10 maximum |
Étape 0 : Migration à partir de l'intégration du SDK Media Home
Mapper les modèles de données à partir de l'intégration existante
Si vous effectuez une migration depuis une intégration Media Home existante, le tableau suivant explique comment mapper les modèles de données des SDK existants avec le nouveau SDK Engage :
Équivalent d'intégration MediaHomeVideoContract | Équivalent d'intégration du SDK Engage |
---|---|
com.google.android.mediahome.video.PreviewChannel
|
com.google.android.engage.common.datamodel.RecommendationCluster
|
com.google.android.mediahome.video.PreviewChannel.Builder
|
com.google.android.engage.common.datamodel.RecommendationCluster.Builder
|
com.google.android.mediahome.video.PreviewChannelHelper
|
com.google.android.engage.video.service.AppEngageVideoClient
|
com.google.android.mediahome.video.PreviewProgram |
Divisé en plusieurs classes : EventVideo , LiveStreamingVideo , Movie , TvEpisode , TvSeason , TvShow , VideoClipEntity
|
com.google.android.mediahome.video.PreviewProgram.Builder
|
Divisé en compilateurs dans des classes distinctes : EventVideo , LiveStreamingVideo , Movie , TvEpisode , TvSeason , TvShow , VideoClipEntity
|
com.google.android.mediahome.video.VideoContract |
Plus nécessaire |
com.google.android.mediahome.video.WatchNextProgram |
Divisé en attributs dans des classes distinctes : EventVideoEntity , LiveStreamingVideoEntity , MovieEntity , TvEpisodeEntity , TvSeasonEntity , TvShowEntity , VideoClipEntity
|
com.google.android.mediahome.video.WatchNextProgram.Builder
|
Divisé en attributs dans des classes distinctes : EventVideoEntity , LiveStreamingVideoEntity , MovieEntity , TvEpisodeEntity , TvSeasonEntity , TvShowEntity , VideoClipEntity
|
Publier les clusters dans le SDK Media Home par rapport au SDK Engage
Avec le SDK Media Home, les clusters et les entités étaient publiés via des API distinctes :
// 1. Fetch existing channels
List<PreviewChannel> channels = PreviewChannelHelper.getAllChannels();
// 2. If there are no channels, publish new channels
long channelId = PreviewChannelHelper.publishChannel(builder.build());
// 3. If there are existing channels, decide whether to update channel contents
PreviewChannelHelper.updatePreviewChannel(channelId, builder.build());
// 4. Delete all programs in the channel
PreviewChannelHelper.deleteAllPreviewProgramsByChannelId(channelId);
// 5. publish new programs in the channel
PreviewChannelHelper.publishPreviewProgram(builder.build());
Avec le SDK Engage, la publication de clusters et d'entités est combinée en un seul appel d'API. Toutes les entités appartenant à un cluster sont publiées avec ce cluster :
Kotlin
RecommendationCluster.Builder() .addEntity(MOVIE_ENTITY) .addEntity(MOVIE_ENTITY) .addEntity(MOVIE_ENTITY) .setTitle("Top Picks For You") .build()
Java
new RecommendationCluster.Builder() .addEntity(MOVIE_ENTITY) .addEntity(MOVIE_ENTITY) .addEntity(MOVIE_ENTITY) .setTitle("Top Picks For You") .build();
Étape 1 : Fournir les données d'entité
Le SDK a défini différentes entités pour représenter chaque type d'élément. Nous prenons en charge les entités suivantes pour la catégorie Watch (Regarder) :
Le tableau suivant présente les attributs et les exigences pour chaque type.
MovieEntity
Attribut | Obligatoire ? | Notes |
---|---|---|
Nom | Obligatoire | |
Images poster | Obligatoire | Vous devez fournir au moins une image au format approprié. Il est préférable d'utiliser le format paysage, mais nous vous recommandons d'utiliser à la fois des images au format portrait et paysage pour différents scénarios.
Consultez la section Caractéristiques des images pour en savoir plus. |
URI de lecture | Obligatoire |
Lien profond vers l'application du fournisseur permettant de commencer à regarder le film. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
URI de la page d'informations | Facultatif |
Lien profond vers l'application du fournisseur pour afficher les détails du film. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
Date de sortie | Obligatoire | En millisecondes (epoch) |
Disponibilité | Obligatoire | AVAILABLE (DISPONIBLE) : le contenu est accessible à l'utilisateur sans aucune autre action. FREE_WITH_SUBSCRIPTION (INCLUS AVEC L'ABONNEMENT) : le contenu est disponible une fois que l'utilisateur a souscrit un abonnement. PAID_CONTENT (CONTENU PAYANT) : le contenu nécessite un achat ou une location. PURCHASED (ACHETÉ) : le contenu a été acheté ou loué par l'utilisateur. |
Prix de l'offre | Facultatif | Texte libre |
Durée | Obligatoire | En millisecondes |
Genre | Obligatoire | Texte libre |
Classification du contenu | Obligatoire | Texte libre (respectez la norme du secteur). (Exemple) |
Regarder le type suivant | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et doit correspondre à l'un des quatre types suivants : CONTINUE (CONTINUER) : l'utilisateur a déjà regardé plus de 1 minute de ce contenu. NEW (NOUVEAU) : l'utilisateur a regardé tous les épisodes disponibles d'un contenu spécifique, mais un nouvel épisode est désormais disponible. Seul cet épisode n'a pas encore été regardé. Cela fonctionne pour les émissions télévisées, les matchs de football enregistrés d'une série, etc. NEXT (SUIVANT) : l'utilisateur a regardé un ou plusieurs épisodes complets d'un contenu, mais il lui reste encore plusieurs épisodes ou un seul épisode (dans ce cas, l'épisode restant ne doit pas être "NEW" (NOUVEAU) et doit être disponible avant que l'utilisateur ait commencé à regarder le contenu sous forme d'épisodes). WATCHLIST (MA LISTE) : l'utilisateur a explicitement choisi d'ajouter un film, un événement ou une série à une liste pour organiser manuellement ce qu'il souhaite regarder ensuite. |
Durée du dernier engagement | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation". En millisecondes (epoch) |
Dernière position de lecture | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et que WatchNextType indique CONTINUE (CONTINUER). En millisecondes (epoch) |
TvShowEntity
Attribut | Obligatoire ? | Notes |
---|---|---|
Nom | Obligatoire | |
Images poster | Obligatoire | Vous devez fournir au moins une image au format approprié. Il est préférable d'utiliser le format paysage, mais nous vous recommandons d'utiliser à la fois des images au format portrait et paysage pour différents scénarios.
Consultez la section Caractéristiques des images pour en savoir plus. |
URI de la page d'informations | Obligatoire |
Lien profond vers l'application du fournisseur pour afficher les détails de l'émission télévisée. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes |
URI de lecture | Facultatif |
Lien profond vers l'application du fournisseur pour commencer à regarder l'émission télévisée. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
Date de diffusion du premier épisode | Obligatoire | En millisecondes (epoch) |
Date de diffusion du dernier épisode | Facultatif | En millisecondes (epoch) |
Disponibilité | Obligatoire | AVAILABLE (DISPONIBLE) : le contenu est accessible à l'utilisateur sans aucune autre action. FREE_WITH_SUBSCRIPTION (INCLUS AVEC L'ABONNEMENT) : le contenu est disponible une fois que l'utilisateur a souscrit un abonnement. PAID_CONTENT (CONTENU PAYANT) : le contenu nécessite un achat ou une location. PURCHASED (ACHETÉ) : le contenu a été acheté ou loué par l'utilisateur. |
Prix de l'offre | Facultatif | Texte libre |
Nombre de saisons | Obligatoire | Nombre entier positif |
Genre | Obligatoire | Texte libre |
Classification du contenu | Obligatoire | Texte libre, conforme aux normes du secteur (Exemple) |
Regarder le type suivant | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et doit correspondre à l'un des quatre types suivants : CONTINUE (CONTINUER) : l'utilisateur a déjà regardé plus de 1 minute de ce contenu. NEW (NOUVEAU) : l'utilisateur a regardé tous les épisodes disponibles d'un contenu spécifique, mais un nouvel épisode est désormais disponible. Seul cet épisode n'a pas encore été regardé. Cela fonctionne pour les émissions télévisées, les matchs de football enregistrés d'une série, etc. NEXT (SUIVANT) : l'utilisateur a regardé un ou plusieurs épisodes complets d'un contenu, mais il lui reste encore plusieurs épisodes ou un seul épisode (dans ce cas, l'épisode restant ne doit pas être "NEW" (NOUVEAU) et doit être disponible avant que l'utilisateur ait commencé à regarder le contenu sous forme d'épisodes). WATCHLIST (MA LISTE) : l'utilisateur a explicitement choisi d'ajouter un film, un événement ou une série à une liste pour organiser manuellement ce qu'il souhaite regarder ensuite. |
Durée du dernier engagement | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation". En millisecondes (epoch) |
Dernière position de lecture | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et que WatchNextType indique CONTINUE (CONTINUER). En millisecondes (epoch) |
TvSeasonEntity
Attribut | Obligatoire ? | Notes |
---|---|---|
Nom | Obligatoire | |
Images poster | Obligatoire | Vous devez fournir au moins une image au format approprié. Il est préférable d'utiliser le format paysage, mais nous vous recommandons d'utiliser à la fois des images au format portrait et paysage pour différents scénarios.
Consultez la section Caractéristiques des images pour en savoir plus. |
URI de la page d'informations | Obligatoire |
Lien profond vers l'application du fournisseur pour afficher les détails de la saison de l'émission télévisée. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
URI de lecture | Facultatif |
Lien profond vers l'application du fournisseur pour commencer à regarder la saison de l'émission télévisée. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
Affichage du numéro de la saison |
Facultatif Disponible dans la version 1.3.1 |
Chaîne |
Date de diffusion du premier épisode | Obligatoire | En millisecondes (epoch) |
Date de diffusion du dernier épisode | Facultatif | En millisecondes (epoch) |
Disponibilité | Obligatoire | AVAILABLE (DISPONIBLE) : le contenu est accessible à l'utilisateur sans aucune autre action. FREE_WITH_SUBSCRIPTION (INCLUS AVEC L'ABONNEMENT) : le contenu est disponible une fois que l'utilisateur a souscrit un abonnement. PAID_CONTENT (CONTENU PAYANT) : le contenu nécessite un achat ou une location. PURCHASED (ACHETÉ) : le contenu a été acheté ou loué par l'utilisateur. |
Prix de l'offre | Facultatif | Texte libre |
Nombre d'épisodes | Obligatoire | Nombre entier positif |
Genre | Obligatoire | Texte libre |
Classification du contenu | Obligatoire | Texte libre (respectez la norme du secteur). (Exemple) |
Regarder le type suivant | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et doit correspondre à l'un des quatre types suivants : CONTINUE (CONTINUER) : l'utilisateur a déjà regardé plus de 1 minute de ce contenu. NEW (NOUVEAU) : l'utilisateur a regardé tous les épisodes disponibles d'un contenu spécifique, mais un nouvel épisode est désormais disponible. Seul cet épisode n'a pas encore été regardé. Cela fonctionne pour les émissions télévisées, les matchs de football enregistrés d'une série, etc. NEXT (SUIVANT) : l'utilisateur a regardé un ou plusieurs épisodes complets d'un contenu, mais il lui reste encore plusieurs épisodes ou un seul épisode (dans ce cas, l'épisode restant ne doit pas être "NEW" (NOUVEAU) et doit être disponible avant que l'utilisateur ait commencé à regarder le contenu sous forme d'épisodes). WATCHLIST (MA LISTE) : l'utilisateur a explicitement choisi d'ajouter un film, un événement ou une série à une liste pour organiser manuellement ce qu'il souhaite regarder ensuite. |
Durée du dernier engagement | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation". En millisecondes (epoch) |
Dernière position de lecture | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et que WatchNextType indique CONTINUE (CONTINUER). En millisecondes (epoch) |
TvEpisodeEntity
Attribut | Obligatoire ? | Notes |
---|---|---|
Nom | Obligatoire | |
Images poster | Obligatoire | Vous devez fournir au moins une image au format approprié. Il est préférable d'utiliser le format paysage, mais nous vous recommandons d'utiliser à la fois des images au format portrait et paysage pour différents scénarios.
Consultez la section Caractéristiques des images pour en savoir plus. |
URI de lecture | Obligatoire |
Lien profond vers l'application du fournisseur pour commencer à regarder l'épisode. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
URI de la page d'informations | Facultatif |
Lien profond vers l'application du fournisseur pour afficher les détails de l'épisode de l'émission télévisée. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
Affichage du numéro de l'épisode |
Facultatif Disponible dans la version 1.3.1 |
Chaîne |
Date de diffusion | Obligatoire | En millisecondes (epoch) |
Disponibilité | Obligatoire | AVAILABLE (DISPONIBLE) : le contenu est accessible à l'utilisateur sans aucune autre action. FREE_WITH_SUBSCRIPTION (INCLUS AVEC L'ABONNEMENT) : le contenu est disponible une fois que l'utilisateur a souscrit un abonnement. PAID_CONTENT (CONTENU PAYANT) : le contenu nécessite un achat ou une location. PURCHASED (ACHETÉ) : le contenu a été acheté ou loué par l'utilisateur. |
Prix de l'offre | Facultatif | Texte libre |
Durée | Obligatoire | La valeur doit être positive en millisecondes. |
Genre | Obligatoire | Texte libre |
Classification du contenu | Obligatoire | Texte libre, conforme aux normes du secteur (Exemple) |
Regarder le type suivant | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et doit correspondre à l'un des quatre types suivants : CONTINUE (CONTINUER) : l'utilisateur a déjà regardé plus de 1 minute de ce contenu. NEW (NOUVEAU) : l'utilisateur a regardé tous les épisodes disponibles d'un contenu spécifique, mais un nouvel épisode est désormais disponible. Seul cet épisode n'a pas encore été regardé. Cela fonctionne pour les émissions télévisées, les matchs de football enregistrés d'une série, etc. NEXT (SUIVANT) : l'utilisateur a regardé un ou plusieurs épisodes complets d'un contenu, mais il lui reste encore plusieurs épisodes ou un seul épisode (dans ce cas, l'épisode restant ne doit pas être "NEW" (NOUVEAU) et doit être disponible avant que l'utilisateur ait commencé à regarder le contenu sous forme d'épisodes). WATCHLIST (MA LISTE) : l'utilisateur a explicitement choisi d'ajouter un film, un événement ou une série à une liste pour organiser manuellement ce qu'il souhaite regarder ensuite. |
Durée du dernier engagement | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation". En millisecondes (epoch) |
Dernière position de lecture | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et que WatchNextType indique CONTINUE (CONTINUER). En millisecondes (epoch) |
LiveStreamingVideoEntity
Attribut | Obligatoire ? | Notes |
---|---|---|
Nom | Obligatoire | |
Images poster | Obligatoire | Vous devez fournir au moins une image au format approprié. Il est préférable d'utiliser le format paysage, mais nous vous recommandons d'utiliser à la fois des images au format portrait et paysage pour différents scénarios.
Consultez la section Caractéristiques des images pour en savoir plus. |
URI de lecture | Obligatoire |
Lien profond vers l'application du fournisseur permettant de commencer à regarder la vidéo. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
Présentateur | Obligatoire | Texte libre |
Heure de début | Facultatif | En millisecondes (epoch) |
Heure de fin | Facultatif | En millisecondes (epoch) |
Nombre de vues | Facultatif | Texte libre (doit être localisé) |
Regarder le type suivant | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et doit correspondre à l'un des quatre types suivants : CONTINUE (CONTINUER) : l'utilisateur a déjà regardé plus de 1 minute de ce contenu. NEW (NOUVEAU) : l'utilisateur a regardé tous les épisodes disponibles d'un contenu spécifique, mais un nouvel épisode est désormais disponible. Seul cet épisode n'a pas encore été regardé. Cela fonctionne pour les émissions télévisées, les matchs de football enregistrés d'une série, etc. NEXT (SUIVANT) : l'utilisateur a regardé un ou plusieurs épisodes complets d'un contenu, mais il lui reste encore plusieurs épisodes ou un seul épisode (dans ce cas, l'épisode restant ne doit pas être "NEW" (NOUVEAU) et doit être disponible avant que l'utilisateur ait commencé à regarder le contenu sous forme d'épisodes). WATCHLIST (MA LISTE) : l'utilisateur a explicitement choisi d'ajouter un film, un événement ou une série à une liste pour organiser manuellement ce qu'il souhaite regarder ensuite. |
Durée du dernier engagement | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation". En millisecondes (epoch) |
Dernière position de lecture | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et que WatchNextType indique CONTINUE (CONTINUER). En millisecondes (epoch) |
VideoClipEntity
L'objet VideoClipEntity
représente une entité vidéo provenant de réseaux sociaux tels que TikTok ou YouTube.
Attribut | Obligatoire ? | Notes |
---|---|---|
Nom | Obligatoire | |
Images poster | Obligatoire | Vous devez fournir au moins une image au format approprié. Il est préférable d'utiliser le format paysage, mais nous vous recommandons d'utiliser à la fois des images au format portrait et paysage pour différents scénarios.
Consultez la section Caractéristiques des images pour en savoir plus. |
URI de lecture | Obligatoire |
Lien profond vers l'application du fournisseur permettant de commencer à regarder la vidéo. Remarque : Vous pouvez utiliser des liens profonds pour l'attribution. Consultez ces questions fréquentes. |
Date de création | Obligatoire | En millisecondes (epoch) |
Durée | Obligatoire | La valeur doit être positive en millisecondes. |
Créateur | Obligatoire | Texte libre |
Image du créateur | Facultatif | Image de l'avatar du créateur |
Nombre de vues | Facultatif | Texte libre (doit être localisé) |
Regarder le type suivant | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et doit correspondre à l'un des quatre types suivants : CONTINUE (CONTINUER) : l'utilisateur a déjà regardé plus de 1 minute de ce contenu. NEW (NOUVEAU) : l'utilisateur a regardé tous les épisodes disponibles d'un contenu spécifique, mais un nouvel épisode est désormais disponible. Seul cet épisode n'a pas encore été regardé. Cela fonctionne pour les émissions télévisées, les matchs de football enregistrés d'une série, etc. NEXT (SUIVANT) : l'utilisateur a regardé un ou plusieurs épisodes complets d'un contenu, mais il lui reste encore plusieurs épisodes ou un seul épisode (dans ce cas, l'épisode restant ne doit pas être "NEW" (NOUVEAU) et doit être disponible avant que l'utilisateur ait commencé à regarder le contenu sous forme d'épisodes). WATCHLIST (MA LISTE) : l'utilisateur a explicitement choisi d'ajouter un film, un événement ou une série à une liste pour organiser manuellement ce qu'il souhaite regarder ensuite. |
Durée du dernier engagement | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation". En millisecondes (epoch) |
Dernière position de lecture | Obligatoire sous certaines conditions | Doit être fourni lorsque l'élément se trouve dans le cluster "Continuation" et que WatchNextType indique CONTINUE (CONTINUER). En millisecondes (epoch) |
Caractéristiques des images
La section suivante liste les spécifications requises pour les composants Image:
Formats des fichiers
PNG, JPG, GIF statique, WebP
Taille maximale des fichiers
5 120 Ko
Autres recommandations
- Zone de sécurité de l'image : placez le contenu important dans les 80 % les plus au centre de l'image.
Exemple
Kotlin
var movie = MovieEntity.Builder() .setName("Avengers") .addPosterImage(Image.Builder() .setImageUri(Uri.parse("http://www.x.com/image.png")) .setImageHeightInPixel(960) .setImageWidthInPixel(408) .build()) .setPlayBackUri(Uri.parse("http://tv.com/playback/1")) .setReleaseDateEpochMillis(1633032895L) .setAvailability(ContentAvailability.AVAILABILITY_AVAILABLE) .setDurationMillis(12345678L) .addGenre("action") .addContentRating("R") .setWatchNextType(WatchNextType.TYPE_NEW) .setLastEngagementTimeMillis(1664568895L) .build()
Java
MovieEntity movie = new MovieEntity.Builder() .setName("Avengers") .addPosterImage( new Image.Builder() .setImageUri(Uri.parse("http://www.x.com/image.png")) .setImageHeightInPixel(960) .setImageWidthInPixel(408) .build()) .setPlayBackUri(Uri.parse("http://tv.com/playback/1")) .setReleaseDateEpochMillis(1633032895L) .setAvailability(ContentAvailability.AVAILABILITY_AVAILABLE) .setDurationMillis(12345678L) .addGenre("action") .addContentRating("R") .setWatchNextType(WatchNextType.TYPE_NEW) .setLastEngagementTimeMillis(1664568895L) .build();
Étape 2 : Fournir les données de cluster
Il est recommandé d'exécuter la tâche de publication de contenu en arrière-plan (par exemple, à l'aide de WorkManager) et de la programmer régulièrement ou sur la base d'un événement précis (par exemple, chaque fois que l'utilisateur ouvre l'application ou lorsqu'il vient d'ajouter quelque chose à son panier).
AppEngagePublishClient
permet la publication des clusters. Les API suivantes sont disponibles dans le client :
isServiceAvailable
publishRecommendationClusters
publishFeaturedCluster
publishContinuationCluster
publishUserAccountManagementRequest
updatePublishStatus
deleteRecommendationsClusters
deleteFeaturedCluster
deleteContinuationCluster
deleteUserManagementCluster
deleteClusters
isServiceAvailable
Cette API permet de vérifier si le service est disponible pour l'intégration et de déterminer si le contenu peut être présenté sur l'appareil.
Kotlin
client.isServiceAvailable.addOnCompleteListener { task -> if (task.isSuccessful) { // Handle IPC call success if(task.result) { // Service is available on the device, proceed with content publish // calls. } else { // Service is not available, no further action is needed. } } else { // The IPC call itself fails, proceed with error handling logic here, // such as retry. } }
Java
client.isServiceAvailable().addOnCompleteListener(task - > { if (task.isSuccessful()) { // Handle success if(task.getResult()) { // Service is available on the device, proceed with content publish // calls. } else { // Service is not available, no further action is needed. } } else { // The IPC call itself fails, proceed with error handling logic here, // such as retry. } });
publishRecommendationClusters
Cette API permet de publier une liste d'objets RecommendationCluster
.
Kotlin
client.publishRecommendationClusters( PublishRecommendationClustersRequest.Builder() .addRecommendationCluster( RecommendationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .setTitle("Top Picks For You") .build() ) .build() )
Java
client.publishRecommendationClusters( new PublishRecommendationClustersRequest.Builder() .addRecommendationCluster( new RecommendationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .setTitle("Top Picks For You") .build()) .build());
Lorsque le service reçoit la requête, les actions suivantes ont lieu dans une seule transaction :
- Les données
RecommendationCluster
existantes du développeur partenaire sont supprimées. - Les données de la requête sont analysées et stockées dans le cluster "Recommendation" mis à jour.
En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
publishFeaturedCluster
Cette API permet de publier une liste d'objets FeaturedCluster
.
Kotlin
client.publishFeaturedCluster( PublishFeaturedClusterRequest.Builder() .setFeaturedCluster( FeaturedCluster.Builder() .addEntity(entity1) .addEntity(entity2) .build()) .build())
Java
client.publishFeaturedCluster( new PublishFeaturedClustersRequest.Builder() .addFeaturedCluster( new FeaturedCluster.Builder() .addEntity(entity1) .addEntity(entity2) .build()) .build());
Lorsque le service reçoit la requête, les actions suivantes ont lieu dans une seule transaction :
- Les données
FeaturedCluster
existantes du développeur partenaire sont supprimées. - Les données de la requête sont analysées et stockées dans le cluster "Featured" mis à jour.
En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
publishContinuationCluster
Cette API permet de publier un objet ContinuationCluster
.
Kotlin
client.publishContinuationCluster( PublishContinuationClusterRequest.Builder() .setContinuationCluster( ContinuationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .build()) .build())
Java
client.publishContinuationCluster( new PublishContinuationClusterRequest.Builder() .setContinuationCluster( new ContinuationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .build()) .build());
Lorsque le service reçoit la requête, les actions suivantes ont lieu dans une seule transaction :
- Les données
ContinuationCluster
existantes du développeur partenaire sont supprimées. - Les données de la requête sont analysées et stockées dans le cluster "Continuation" mis à jour.
En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
publishUserAccountManagementRequest
Cette API permet de publier une fiche de connexion. L'action de connexion redirige les utilisateurs vers la page de connexion de l'application afin que celle-ci puisse publier du contenu (ou fournir un contenu plus personnalisé).
Les métadonnées suivantes font partie de la fiche de connexion :
Attribut | Obligatoire ? | Description |
---|---|---|
URI d'action | Obligatoire | Lien profond vers l'action (par exemple, accès à la page de connexion de l'application) |
Image | Facultatif : si aucun titre n'est fourni, vous devez en fournir un |
Image affichée sur la fiche Images au format 16:9 avec une résolution de 1 264 x 712 |
Titre | Facultatif : si aucune image n'est fournie, vous devez en fournir une | Titre sur la fiche |
Texte de l'action | Facultatif | Texte affiché sur l'incitation à l'action (par exemple, "Se connecter") |
Sous-titre | Facultatif | Sous-titre facultatif sur la fiche |
Kotlin
var SIGN_IN_CARD_ENTITY = SignInCardEntity.Builder() .addPosterImage( Image.Builder() .setImageUri(Uri.parse("http://www.x.com/image.png")) .setImageHeightInPixel(500) .setImageWidthInPixel(500) .build()) .setActionText("Sign In") .setActionUri(Uri.parse("http://xx.com/signin")) .build() client.publishUserAccountManagementRequest( PublishUserAccountManagementRequest.Builder() .setSignInCardEntity(SIGN_IN_CARD_ENTITY) .build());
Java
SignInCardEntity SIGN_IN_CARD_ENTITY = new SignInCardEntity.Builder() .addPosterImage( new Image.Builder() .setImageUri(Uri.parse("http://www.x.com/image.png")) .setImageHeightInPixel(500) .setImageWidthInPixel(500) .build()) .setActionText("Sign In") .setActionUri(Uri.parse("http://xx.com/signin")) .build(); client.publishUserAccountManagementRequest( new PublishUserAccountManagementRequest.Builder() .setSignInCardEntity(SIGN_IN_CARD_ENTITY) .build());
Lorsque le service reçoit la requête, les actions suivantes ont lieu dans une seule transaction :
- Les données
UserAccountManagementCluster
existantes du développeur partenaire sont supprimées. - Les données de la requête sont analysées et stockées dans le cluster "UserAccountManagementCluster" mis à jour.
En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
updatePublishStatus
Si, pour une raison opérationnelle interne, aucun des clusters n'est publié, nous vous recommandons vivement de mettre à jour l'état de publication à l'aide de l'API updatePublishStatus. Ce point est important pour les raisons suivantes :
- Il est essentiel d'indiquer l'état dans tous les scénarios, même lorsque le contenu est publié (STATUS == PUBLISHED) pour renseigner les tableaux de bord qui utilisent cet état explicite afin de transmettre l'état et d'autres métriques de votre intégration.
- Si aucun contenu n'est publié, mais que l'état de l'intégration fonctionne correctement (STATUS == NOT_PUBLISHED), Google peut éviter de déclencher des alertes dans les tableaux de bord concernant l'état de l'application. Cela confirme que le contenu n'est pas publié en raison d'une situation attendue du point de vue du fournisseur.
- Cela permet aux développeurs de fournir des informations concernant la date de publication des données.
- Google peut utiliser les codes d'état pour encourager l'utilisateur à effectuer certaines actions dans l'application, afin qu'il puisse afficher ou contourner le contenu de l'application.
Voici la liste des codes d'état de publication éligibles :
// Content is published
AppEngagePublishStatusCode.PUBLISHED,
// Content is not published as user is not signed in
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN,
// Content is not published as user is not subscribed
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SUBSCRIPTION,
// Content is not published as user location is ineligible
AppEngagePublishStatusCode.NOT_PUBLISHED_INELIGIBLE_LOCATION,
// Content is not published as there is no eligible content
AppEngagePublishStatusCode.NOT_PUBLISHED_NO_ELIGIBLE_CONTENT,
// Content is not published as the feature is disabled by the client
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_FEATURE_DISABLED_BY_CLIENT,
// Content is not published as the feature due to a client error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_CLIENT_ERROR,
// Content is not published as the feature due to a service error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_SERVICE_ERROR,
// Content is not published due to some other reason
// Reach out to engage-developers@ before using this enum.
AppEngagePublishStatusCode.NOT_PUBLISHED_OTHER
Si le contenu n'est pas publié parce que l'utilisateur n'est pas connecté, Google vous recommande de publier la fiche de connexion. Si, pour une raison quelconque, les fournisseurs ne peuvent pas publier la fiche de connexion, nous vous recommandons d'appeler l'API updatePublishStatus avec le code d'état NOT_PUBLISHED_REQUIRES_SIGN_IN.
Kotlin
client.updatePublishStatus( PublishStatusRequest.Builder() .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN) .build())
Java
client.updatePublishStatus( new PublishStatusRequest.Builder() .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN) .build());
deleteRecommendationClusters
Cette API permet de supprimer le contenu des clusters "Recommendation".
Kotlin
client.deleteRecommendationClusters()
Java
client.deleteRecommendationClusters();
Lorsque le service reçoit la requête, il supprime les données existantes des clusters "Recommendation". En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
deleteFeaturedCluster
Cette API permet de supprimer le contenu du cluster "Featured".
Kotlin
client.deleteFeaturedCluster()
Java
client.deleteFeaturedCluster();
Lorsque le service reçoit la requête, il supprime les données existantes du cluster "Featured". En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
deleteContinuationCluster
Cette API permet de supprimer le contenu du cluster "Continuation".
Kotlin
client.deleteContinuationCluster()
Java
client.deleteContinuationCluster();
Lorsque le service reçoit la requête, il supprime les données existantes du cluster "Continuation". En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
deleteUserManagementCluster
Cette API permet de supprimer le contenu du cluster "UserAccountManagement".
Kotlin
client.deleteUserManagementCluster()
Java
client.deleteUserManagementCluster();
Lorsque le service reçoit la requête, il supprime les données existantes du cluster "UserAccountManagement". En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
deleteClusters
Cette API permet de supprimer le contenu d'un type de cluster donné.
Kotlin
client.deleteClusters( DeleteClustersRequest.Builder() .addClusterType(ClusterType.TYPE_CONTINUATION) .addClusterType(ClusterType.TYPE_FEATURED) .addClusterType(ClusterType.TYPE_RECOMMENDATION) .build())
Java
client.deleteClusters( new DeleteClustersRequest.Builder() .addClusterType(ClusterType.TYPE_CONTINUATION) .addClusterType(ClusterType.TYPE_FEATURED) .addClusterType(ClusterType.TYPE_RECOMMENDATION) .build());
Lorsque le service reçoit la requête, il supprime les données existantes de tous les clusters correspondant aux types de clusters spécifiés. Les clients peuvent choisir de transmettre un ou plusieurs types de clusters. En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.
Gestion des exceptions
Il est fortement recommandé d'écouter le résultat de la tâche à partir des API de publication afin qu'une action de suivi puisse être effectuée pour récupérer et renvoyer une tâche réussie.
Kotlin
client.publishRecommendationClusters( PublishRecommendationClustersRequest.Builder() .addRecommendationCluster(..) .build()) .addOnCompleteListener { task -> if (task.isSuccessful) { // do something } else { val exception = task.exception if (exception is AppEngageException) { @AppEngageErrorCode val errorCode = exception.errorCode if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) { // do something } } } }
Java
client.publishRecommendationClusters( new PublishRecommendationClustersRequest.Builder() .addRecommendationCluster(...) .build()) .addOnCompleteListener( task -> { if (task.isSuccessful()) { // do something } else { Exception exception = task.getException(); if (exception instanceof AppEngageException) { @AppEngageErrorCode int errorCode = ((AppEngageException) exception).getErrorCode(); if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) { // do something } } } });
L'erreur est renvoyée au format AppEngageException
. La cause est incluse sous la forme d'un code d'erreur.
Code d'erreur | Nom de l'erreur | Remarque |
---|---|---|
1 |
SERVICE_NOT_FOUND |
Le service n'est pas disponible sur l'appareil donné. |
2 |
SERVICE_NOT_AVAILABLE |
Le service est disponible sur l'appareil donné, mais pas au moment de l'appel (par exemple, il est explicitement désactivé). |
3 |
SERVICE_CALL_EXECUTION_FAILURE |
L'exécution de la tâche a échoué en raison de problèmes de thread. Dans ce cas, vous pouvez réessayer. |
4 |
SERVICE_CALL_PERMISSION_DENIED |
L'appelant n'est pas autorisé à effectuer l'appel du service. |
5 |
SERVICE_CALL_INVALID_ARGUMENT |
La requête contient des données non valides (par exemple, un nombre plus élevé que le nombre de clusters autorisé). |
6 |
SERVICE_CALL_INTERNAL |
Une erreur s'est produite au niveau du service. |
7 |
SERVICE_CALL_RESOURCE_EXHAUSTED |
L'appel du service est effectué trop fréquemment. |
Étape 3 : Gérer les intents de diffusion
En plus d'effectuer des appels d'API de publication de contenu via une tâche, vous devez également configurer un objet BroadcastReceiver
pour recevoir la requête de publication de contenu.
L'objectif des intents de diffusion est principalement de réactiver des applications et de forcer la synchronisation des données. Les intents de diffusion ne sont pas conçus pour être envoyés très fréquemment. Ils ne se déclenchent que lorsque le service Engage détermine que le contenu est peut-être obsolète (par exemple, s'il date d'il y a une semaine). De cette façon, l'utilisateur a plus de chances de bénéficier d'une expérience de contenu actualisée, même si l'application n'a pas été exécutée pendant une longue période.
Le BroadcastReceiver
doit être configuré de deux manières :
- Enregistrez dynamiquement une instance de la classe
BroadcastReceiver
à l'aide deContext.registerReceiver()
. Cela permet la communication à partir d'applications restées actives en mémoire.
Kotlin
class AppEngageBroadcastReceiver : BroadcastReceiver(){ // Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast // is received // Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received // Trigger continuation cluster publish when PUBLISH_CONTINUATION broadcast is // received } fun registerBroadcastReceivers(context: Context){ var context = context context = context.applicationContext // Register Recommendation Cluster Publish Intent context.registerReceiver(AppEngageBroadcastReceiver(), IntentFilter(Intents.ACTION_PUBLISH_RECOMMENDATION)) // Register Featured Cluster Publish Intent context.registerReceiver(AppEngageBroadcastReceiver(), IntentFilter(Intents.ACTION_PUBLISH_FEATURED)) // Register Continuation Cluster Publish Intent context.registerReceiver(AppEngageBroadcastReceiver(), IntentFilter(Intents.ACTION_PUBLISH_CONTINUATION)) }
Java
class AppEngageBroadcastReceiver extends BroadcastReceiver { // Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast // is received // Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received // Trigger continuation cluster publish when PUBLISH_CONTINUATION broadcast is // received } public static void registerBroadcastReceivers(Context context) { context = context.getApplicationContext(); // Register Recommendation Cluster Publish Intent context.registerReceiver(new AppEngageBroadcastReceiver(), new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_RECOMMENDATION)); // Register Featured Cluster Publish Intent context.registerReceiver(new AppEngageBroadcastReceiver(), new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_FEATURED)); // Register Continuation Cluster Publish Intent context.registerReceiver(new AppEngageBroadcastReceiver(), new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_CONTINUATION)); }
- Déclarez une implémentation de manière statique avec la balise
<receiver>
dans le fichierAndroidManifest.xml
. Cela permet à l'application de recevoir des intents de diffusion lorsqu'elle n'est pas en cours d'exécution, et de publier le contenu.
<application>
<receiver
android:name=".AppEngageBroadcastReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.google.android.engage.action.PUBLISH_RECOMMENDATION" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.engage.action.PUBLISH_FEATURED" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.engage.action.PUBLISH_CONTINUATION" />
</intent-filter>
</receiver>
</application>
Les intents suivants sont envoyés par le service :
com.google.android.engage.action.PUBLISH_RECOMMENDATION
Nous vous recommandons de démarrer un appelpublishRecommendationClusters
lorsque vous recevez cet intent.com.google.android.engage.action.PUBLISH_FEATURED
Nous vous recommandons de démarrer un appelpublishFeaturedCluster
lors de la réception de cet intent.com.google.android.engage.action.PUBLISH_CONTINUATION
Nous vous recommandons de démarrer un appelpublishContinuationCluster
lors de la réception de cet intent.
Workflow d'intégration
Pour vous procurer un guide par étapes sur la validation de votre intégration une fois celle-ci terminée, consultez la page Workflow d'intégration pour les développeurs d'Engage.
Questions fréquentes
Pour en savoir plus, consultez les questions fréquentes concernant le SDK Engage.
Contact
Contactez engage-developers@google.com si vous avez des questions au cours du processus d'intégration.
Étapes suivantes
Une fois cette intégration effectuée, procédez comme suit :
- Envoyez un e-mail à l'adresse engage-developers@google.com et joignez-y votre APK intégré prêt à être testé par Google.
- Google effectue une vérification et des examens en interne pour s'assurer que l'intégration fonctionne comme prévu. Si des modifications sont nécessaires, nous vous contacterons avec toutes les informations nécessaires.
- Une fois les tests terminés, si aucune modification n'est nécessaire, nous vous informerons que vous pouvez commencer à publier le fichier APK mis à jour et intégré sur le Play Store.
- Une fois que nous aurons confirmé la publication de votre APK mis à jour sur le Play Store, vos clusters Recommendation (Recommandations), Featured (Sélection) et Continuation (Suite) pourront être publiés et visibles par les utilisateurs.