Google está compilando una plataforma integrada en el dispositivo que organiza las apps de los usuarios por verticales y que permite ofrecer una nueva experiencia envolvente para el descubrimiento y el consumo de contenido personalizado en las apps. Esta experiencia de pantalla completa brinda a los socios desarrolladores la oportunidad de mostrar su mejor contenido enriquecido en un canal dedicado fuera de su app.
Esta guía contiene instrucciones para que los socios desarrolladores integren su contenido de audio usando el SDK de Engage para propagar esta nueva área de la plataforma y las plataformas de Google existentes.
Información detallada sobre la integración
Terminología
Esta integración incluye los siguientes tres tipos de clústeres: Recommendation, Continuation y Featured.
En los clústeres de Recommendation, se muestran sugerencias personalizadas de contenido para escuchar de un socio desarrollador individual.
Tus recomendaciones tienen la siguiente estructura:
Clúster de Recommendation: Es una vista de la IU que contiene un grupo de recomendaciones del mismo socio desarrollador.
Entidad: Es un objeto que representa un solo elemento en un clúster. Una entidad puede ser una playlist, un audiolibro, un podcast y mucho más. Consulta la sección para proporcionar los datos de la entidad si quieres obtener una lista de los tipos de entidades compatibles.
El clúster de Continuation muestra contenido de audio reproducido recientemente por los usuarios de varios socios desarrolladores en una sola agrupación de IU. Cada socio desarrollador podrá transmitir un máximo de 10 entidades en el clúster de Continuation.
El clúster de Featured muestra una selección de elementos de varios socios desarrolladores en una sola agrupación de IU. Habrá un solo clúster de Featured, que aparecerá cerca de la parte superior de la IU, con una ubicación de prioridad por sobre todos los clústeres de Recommendation. Cada socio desarrollador podrá transmitir hasta 10 entidades en el clúster de Featured.
Trabajo previo
Nivel de API mínimo: 19
Agrega la biblioteca com.google.android.engage:engage-core
a tu app:
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'
}
Resumen
El diseño se basa en una implementación de un servicio vinculado.
Los datos que un cliente puede publicar están sujetos a los siguientes límites para diferentes tipos de clústeres:
Tipo de clúster | Límites del clúster | Límites máximos de entidades en un clúster |
---|---|---|
Clústeres de Recommendation | 5 como máximo | 50 como máximo |
Clúster de Continuation | 1 como máximo | 10 como máximo |
Clúster de Featured | 1 como máximo | 10 como máximo |
Paso 1: Proporciona los datos de la entidad
El SDK definió distintas entidades para representar cada tipo de elemento. Admitimos las siguientes entidades para la categoría Escuchar:
MusicAlbumEntity
MusicArtistEntity
MusicTrackEntity
MusicVideoEntity
PlaylistEntity
PodcastSeriesEntity
PodcastEpisodeEntity
LiveRadioStationEntity
AudiobookEntity
En los gráficos siguientes, se describen los atributos y requisitos disponibles para cada tipo.
MusicAlbumEntity
El objeto MusicAlbumEntity
representa un álbum de música (por ejemplo, Midnights de Taylor Swift).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | Es el título del álbum de música. |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
URI de la página de información | Obligatorio |
Es el vínculo directo a la app del proveedor para obtener detalles sobre el álbum de música. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Artistas | Obligatorio | Es la lista de artistas del álbum de música. |
URI de reproducción | Opcional |
Es un vínculo directo que comienza a reproducir el álbum en la app del proveedor. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Cantidad de canciones | Opcional | Es la cantidad de canciones en el álbum de música. |
Géneros | Opcional | Es la lista de géneros del álbum de música. |
Formato del álbum | Opcional |
ÁLBUM (incluye disco de larga duración y disco doble de larga duración) Disco de duración extendida SENCILLO Mixtape |
Sellos discográficos | Opcional | Es la lista de sellos discográficos asociados con el álbum. |
Descargados en el dispositivo | Opcional | Es un valor booleano que indica si el álbum de música se descargó en el dispositivo. |
Contenido explícito | Opcional |
Es un valor booleano que indica si el contenido es explícito o no. Los elementos que contienen material explícito o que tienen una advertencia parental se deben configurar como TRUE. Los elementos explícitos aparecen con la etiqueta "E". |
Fecha de lanzamiento | Opcional | Es la fecha de lanzamiento del álbum, expresada en milisegundos de época. |
Duración | Opcional | Es la duración del álbum, expresada en milisegundos. |
Tiempo de participación más reciente | Opcional |
Se recomienda para los elementos del clúster de Continuation. Se puede usar para clasificación. Debe expresarse en milisegundos de época. |
Porcentaje del progreso que se completó | Opcional |
Se recomienda para los elementos del clúster de Continuation. Es un número entero entre 0 y 100. |
MusicArtistEntity
El objeto MusicArtistEntity
representa un artista musical (por ejemplo, Adele).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | Es el nombre del artista musical. |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
URI de la página de información | Obligatorio |
Es el vínculo directo a la app del proveedor para obtener detalles sobre el artista musical. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
URI de reproducción | Opcional |
Es el vínculo directo que comienza a reproducir las canciones del artista en la app del proveedor. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Tiempo de participación más reciente | Opcional |
Se recomienda para los elementos del clúster de Continuation. Se puede usar para clasificación. Debe expresarse en milisegundos de época. |
MusicTrackEntity
El objeto MusicTrackEntity
representa una pista de música (por ejemplo, Yellow de Coldplay).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | Es el título de la pista de música. |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
URI de reproducción | Obligatorio |
Es un vínculo directo que comienza a reproducir la pista de música en la app del proveedor. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
URI de la página de información | Opcional |
Es un vínculo directo a la app del proveedor para obtener detalles sobre la pista de música. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Duración | Opcional | Es la duración de la pista, expresada en milisegundos. |
Álbum | Opcional | Es el nombre del álbum al que pertenece la canción. |
Artistas | Obligatorio | Es la lista de artistas de la pista de música. |
Descargados en el dispositivo | Opcional | Es un valor booleano que indica si la pista de música se descargó en el dispositivo. |
Contenido explícito | Opcional |
Es un valor booleano que indica si el contenido es explícito o no. Los elementos que contienen material explícito o que tienen una advertencia parental se deben configurar como TRUE. Los elementos explícitos aparecen con la etiqueta "E". |
Tiempo de participación más reciente | Opcional |
Se recomienda para los elementos del clúster de Continuation. Se puede usar para clasificación. Debe expresarse en milisegundos de época. |
Porcentaje del progreso que se completó | Opcional |
Se recomienda para los elementos del clúster de Continuation. Es un número entero entre 0 y 100. |
MusicVideoEntity
El objeto MusicVideoEntity
representa un video musical (por ejemplo,
The Weeknd - Take My Breath (video musical oficial)).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | Es el título del video musical. |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
URI de reproducción | Obligatorio |
Es un vínculo directo que comienza a reproducir el video musical en la app del proveedor. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
URI de la página de información | Opcional |
Es un vínculo directo a la app del proveedor para obtener detalles sobre el video musical. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Duración | Opcional | Es la duración del video, expresada en milisegundos. |
Cantidad de vistas | Opcional | Es la cantidad de vistas del video, expresada en formato de texto libre. |
Artistas | Opcional | Es la lista de artistas del video musical. |
Clasificación del contenido | Opcional | Es la lista de clasificaciones de contenido de la pista. |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Descargados en el dispositivo | Opcional | Es un valor booleano que indica si el video musical se descargó en el dispositivo. |
Contenido explícito | Opcional |
Es un valor booleano que indica si el contenido es explícito o no. Los elementos que contienen material explícito o que tienen una advertencia parental se deben configurar como TRUE. Los elementos explícitos aparecen con la etiqueta "E". |
Tiempo de participación más reciente | Opcional |
Se recomienda para los elementos del clúster de Continuation. Se puede usar para clasificación. Debe expresarse en milisegundos de época. |
Porcentaje del progreso que se completó | Opcional |
Se recomienda para los elementos del clúster de Continuation. Es un número entero entre 0 y 100. |
PlaylistEntity
El objeto PlaylistEntity
representa una playlist de música (por ejemplo, la playlist de las 10 canciones principales de EE.UU.).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | Es el título de la playlist. |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
URI de reproducción | Obligatorio |
Es un vínculo directo que comienza a reproducir la playlist de música en la app del proveedor. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
URI de la página de información | Opcional |
Es un vínculo directo a la app del proveedor para obtener detalles sobre la playlist de música. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Duración | Opcional | Es la duración de la playlist, expresada en milisegundos. |
Cantidad de canciones | Opcional | Es la cantidad de canciones en la playlist de música. |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Descargados en el dispositivo | Opcional | Es un valor booleano que indica si la lista de reproducción se descargó en el dispositivo. |
Contenido explícito | Opcional |
Es un valor booleano que indica si el contenido es explícito o no. Los elementos que contienen material explícito o que tienen una advertencia parental se deben configurar como TRUE. Los elementos explícitos aparecen con la etiqueta "E". |
Tiempo de participación más reciente | Opcional |
Se recomienda para los elementos del clúster de Continuation. Se puede usar para clasificación. Debe expresarse en milisegundos de época. |
Porcentaje del progreso que se completó | Opcional |
Se recomienda para los elementos del clúster de Continuation. Es un número entero entre 0 y 100. |
PodcastSeriesEntity
El objeto PodcastSeriesEntity
representa una serie de podcasts (por ejemplo, This American Life).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | Es el título de la serie de podcasts. |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
URI de la página de información | Obligatorio |
Es un vínculo directo a la app del proveedor para obtener detalles sobre la serie de podcasts. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
URI de reproducción | Opcional |
Es un vínculo directo que comienza a reproducir la serie de podcasts en la app del proveedor. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Cantidad de episodios | Opcional | Es la cantidad de episodios de la serie de podcasts. |
Nombre de la producción | Opcional | Es el nombre de la producción de la serie de podcasts. |
Hosts | Opcional | Es la lista de los presentadores de la serie de podcasts. |
Géneros | Opcional | Es la lista de géneros de la serie de podcasts. |
Descargados en el dispositivo | Opcional | Es un valor booleano que indica si el podcast se descargó en el dispositivo. |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Contenido explícito | Opcional |
Es un valor booleano que indica si el contenido es explícito o no. Los elementos que contienen material explícito o que tienen una advertencia parental se deben configurar como TRUE. Los elementos explícitos aparecen con la etiqueta "E". |
Tiempo de participación más reciente | Opcional |
Se recomienda para los elementos del clúster de Continuation. Se puede usar para clasificación. Debe expresarse en milisegundos de época. |
PodcastEpisodeEntity
El objeto PodcastEpisodeEntity
representa un episodio de un podcast (por ejemplo, Spark Bird, episodio 754: This American Life).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | Es el título del episodio del podcast. |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
URI de reproducción | Obligatorio |
Es un vínculo directo que comienza a reproducir el episodio del podcast en la app del proveedor. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Título de la serie de la producción | Obligatorio | Es el nombre de la serie de podcasts a la que pertenece el episodio. |
Duración | Obligatorio | Es la duración del episodio del podcast, expresada en milisegundos. |
Fecha de publicación | Obligatorio | Fecha de publicación del podcast (en milisegundos de época) |
URI de la página de información | Opcional |
Es un vínculo directo a la app del proveedor para obtener detalles sobre el episodio del podcast. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Nombre de la producción | Opcional | Es el nombre de la producción de la serie de podcasts. |
Índice de episodios | Opcional | Es el índice del episodio en la serie (el primer índice es 1). |
Hosts | Opcional | Es la lista de los presentadores del episodio del podcast. |
Géneros | Opcional | Es la lista de géneros del episodio del podcast. |
Descargados en el dispositivo | Opcional | Es un valor booleano que indica si el episodio del podcast se descargó en el dispositivo. |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Podcast de video | Opcional | Es un valor booleano que indica si el episodio del podcast tiene contenido de video. |
Contenido explícito | Opcional |
Es un valor booleano que indica si el contenido es explícito o no. Los elementos que contienen material explícito o que tienen una advertencia parental se deben configurar como TRUE. Los elementos explícitos aparecen con la etiqueta "E". |
Tipo Escuchar a continuación | Opcional |
Recomendado para elementos en el clúster de Continuation TYPE_CONTINUE: Reanuda un elemento de audio sin terminar. TYPE_NEXT: Continúa en un nuevo elemento de una serie. TYPE_NEW: Es un nuevo lanzamiento. |
Tiempo de participación más reciente | Opcional |
Se recomienda para los elementos del clúster de Continuation. Se puede usar para clasificación. Debe expresarse en milisegundos de época. |
Porcentaje del progreso que se completó | Opcional |
Se recomienda para los elementos del clúster de Continuation. Es un número entero entre 0 y 100. |
LiveRadioStationEntity
El objeto LiveRadioStationEntity
representa una estación de radio en vivo (por ejemplo, 98.1 The Breeze).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | Es el título de la estación de radio en vivo. |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
URI de reproducción | Obligatorio |
Es un vínculo directo que comienza a reproducir la estación de radio en la app del proveedor. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
URI de la página de información | Opcional |
Es un vínculo directo a la app del proveedor para obtener detalles sobre la estación de radio. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Frecuencia | Opcional | Es la frecuencia en la que se transmite la estación de radio (por ejemplo, "98.1 FM"). |
Título del programa | Opcional | Es el programa actual que se está reproduciendo en la estación de radio. |
Hosts | Opcional | Es la lista de presentadores de la estación de radio. |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Tiempo de participación más reciente | Opcional |
Se recomienda para los elementos del clúster de Continuation. Se puede usar para clasificación. Debe expresarse en milisegundos de época. |
AudiobookEntity
El objeto AudiobookEntity
representa un audiolibro (por ejemplo, el libro electrónico Becoming, de Michelle Obama).
Atributo | Requisito | Notas |
---|---|---|
Nombre | Obligatorio | |
Imágenes de pósteres | Obligatorio | Se debe proporcionar al menos una imagen. Consulta la sección Especificaciones de imagen para obtener más información. |
Autor | Obligatorio | Se debe proporcionar al menos un nombre de autor. |
Narrador | Obligatorio | Se debe proporcionar al menos el nombre de un narrador. |
URI de vínculo de acción | Obligatorio |
Es el vínculo directo a la app del proveedor del audiolibro. Nota: Puedes usar vínculos directos para la atribución. Consulta estas preguntas frecuentes |
Fecha de publicación | Opcional | Si se proporciona, debe expresarse en milisegundos de época. |
Descripción | Opcional | Si se proporciona, debe tener 200 caracteres o menos. |
Precio | Opcional | Texto libre |
Duración | Opcional | Si se proporciona, debe ser un número positivo. |
Género | Opcional | Es la lista de géneros asociados con el libro. |
Nombre de la serie | Opcional | Es el nombre de la serie a la que pertenece el audiolibro (por ejemplo, Harry Potter). |
Índice de unidades de la serie | Opcional | Es el índice del audiolibro en la serie, en el que 1 es el primer audiolibro de la serie. Por ejemplo, si Harry Potter y el prisionero de Azkaban es el tercer libro de la serie, el índice debe establecerse en 3. |
Tipo Continuar libro | Opcional |
TYPE_CONTINUE: Reanuda un libro sin terminar. TYPE_NEXT: Continúa en un nuevo elemento de una serie. TYPE_NEW: Es un nuevo lanzamiento. |
Tiempo de participación más reciente | Condicionalmente obligatorio | Se debe proporcionar cuando el elemento está en el clúster de Continuation. Debe expresarse en milisegundos de época. |
Porcentaje completado de progreso | Condicionalmente obligatorio |
Se debe proporcionar cuando el elemento está en el clúster de Continuation. Los audiolibros *recién* adquiridos pueden incluirse en la lectura continua clúster. El valor debe ser mayor que 0 y menor que 100. |
DisplayTimeWindow: establece un período para que un contenido se muestre en la plataforma | ||
Fecha y hora de inicio | Opcional |
Es la marca de tiempo de época a partir de la cual se debe mostrar el contenido en la superficie. Si no la estableces, el contenido será apto para mostrarse en la superficie. Debe expresarse en milisegundos de época. |
Fecha y hora de finalización | Opcional |
La marca de tiempo de época a partir de la cual el contenido ya no se mostrará en a la superficie. Si no la estableces, el contenido será apto para mostrarse en la superficie. Debe expresarse en milisegundos de época. |
Especificaciones de imagen
A continuación, se indican las especificaciones obligatorias para los recursos de imagen:
Relación de aspecto | Requisito | Píxeles mínimos | Píxeles recomendados |
---|---|---|---|
Formato cuadrado (1 x 1) | Obligatorio | 300 x 300 | 1,200 x 1,200 |
Formato horizontal (1.91 x 1) | Opcional | 600 x 314 | 1,200 x 628 |
Formato vertical (4 x 5) | Opcional | 480 x 600 | 960 x 1,200 |
Formatos de archivo
PNG, JPG, GIF estático, WebP
Tamaño máximo de los archivos
5120 KB
Recomendaciones adicionales
- Área segura para la imagen: Coloca el contenido importante en el 80% central de la imagen.
Ejemplos
MusicAlbumEntity musicAlbumEntity =
new MusicAlbumEntity.Builder()
.setName(NAME)
.addPosterImage(new Image.Builder()
.setImageUri(Uri.parse("http://www.x.com/image.png"))
.setImageHeightInPixel(960)
.setImageWidthInPixel(408)
.build())
.setPlayBackUri("https://play.google/album/play")
.setInfoPageUri("https://play.google/album/info")
.setDescription("A description of this album.")
.addArtist("Artist")
.addGenre("Genre")
.addMusicLabel("Label")
.addContentRating("Rating")
.setSongsCount(960)
.setReleaseDateEpochMillis(1633032895L)
.setDurationMillis(1633L)
.build();
AudiobookEntity audiobookEntity =
new AudiobookEntity.Builder()
.setName("Becoming")
.addPosterImage(new Image.Builder()
.setImageUri(Uri.parse("http://www.x.com/image.png"))
.setImageHeightInPixel(960)
.setImageWidthInPixel(408)
.build())
.addAuthor("Michelle Obama")
.addNarrator("Michelle Obama")
.setActionLinkUri(
Uri.parse("https://play.google/audiobooks/1"))
.setDurationMillis(16335L)
.setPublishDateEpochMillis(1633032895L)
.setDescription("An intimate, powerful, and inspiring memoir")
.setPrice("$16.95")
.addGenre("biography")
.build();
Paso 2: Proporciona los datos de los clústeres
Se recomienda que el trabajo de publicación de contenido se ejecute en segundo plano (por ejemplo, con WorkManager) y se programe con frecuencia o en eventos (por ejemplo, cada vez que el usuario abre la app o cuando acaba de agregar algo a su carrito).
AppEngagePublishClient
es responsable de publicar los clústeres. Las siguientes APIs están disponibles en el cliente:
isServiceAvailable
publishRecommendationClusters
publishFeaturedCluster
publishContinuationCluster
publishUserAccountManagementRequest
updatePublishStatus
deleteRecommendationsClusters
deleteFeaturedCluster
deleteContinuationCluster
deleteUserManagementCluster
deleteClusters
isServiceAvailable
Esta API se usa para verificar si el servicio está disponible para la integración y si el contenido se puede presentar en el dispositivo.
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
Esta API se usa para publicar una lista de objetos RecommendationCluster
.
Kotlin
client.publishRecommendationClusters( PublishRecommendationClustersRequest.Builder() .addRecommendationCluster( RecommendationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .setTitle("Trending music") .build()) .build())
Java
client.publishRecommendationClusters( new PublishRecommendationClustersRequest.Builder() .addRecommendationCluster( new RecommendationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .setTitle("Trending music") .build()) .build());
Cuando el servicio recibe la solicitud, se realizan las siguientes acciones en una transacción:
- Se quitan los datos existentes de
RecommendationCluster
del socio desarrollador. - Los datos de la solicitud se analizan y se almacenan en el clúster de Recommendation actualizado.
En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
publishFeaturedCluster
Esta API se usa para publicar una lista de objetos FeaturedCluster
.
Kotlin
client.publishFeaturedCluster( PublishFeaturedClusterRequest.Builder() .setFeaturedCluster( FeaturedCluster.Builder() ... .build()) .build())
Java
client.publishFeaturedCluster( new PublishFeaturedClusterRequest.Builder() .setFeaturedCluster( new FeaturedCluster.Builder() ... .build()) .build());
Cuando el servicio recibe la solicitud, se realizan las siguientes acciones en una transacción:
- Se quitan los datos existentes de
FeaturedCluster
del socio desarrollador. - Los datos de la solicitud se analizan y se almacenan en el clúster de Featured actualizado.
En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
publishContinuationCluster
Esta API se usa para publicar un objeto ContinuationCluster
.
Kotlin
client.publishContinuationCluster( PublishContinuationClusterRequest.Builder() .setContinuationCluster( ContinuationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .build()) .build())
Java
client.publishContinuationCluster( PublishContinuationClusterRequest.Builder() .setContinuationCluster( ContinuationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .build()) .build())
Cuando el servicio recibe la solicitud, se realizan las siguientes acciones en una transacción:
- Se quitan los datos existentes de
ContinuationCluster
del socio desarrollador. - Los datos de la solicitud se analizan y se almacenan en el clúster de Continuation actualizado.
En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
publishUserAccountManagementRequest
Esta API se usa para publicar una tarjeta de acceso. La acción de acceso dirige a los usuarios a la página de acceso de la app para que esta pueda publicar contenido (o proporcionar contenido más personalizado).
Los siguientes metadatos forman parte de la tarjeta de acceso:
Atributo | Requisito | Descripción |
---|---|---|
URI de acción | Obligatorio | Vínculo directo a la acción (p. ej., navega a la página de acceso de la app) |
Imagen | Opcional: En caso de que no se proporcione el título, debes brindar uno. |
Imagen que se muestra en la tarjeta Imágenes con una relación de aspecto de 16 × 9, con una resolución de 1264 × 712 |
Título | Opcional: En caso de que no se proporcione la imagen, debes brindar una. | Título en la tarjeta |
Texto de acción | Opcional | Texto que se muestra en la CTA (p. ej., Acceder) |
Subtítulo | Opcional | Subtítulo opcional en la tarjeta |
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());
Cuando el servicio recibe la solicitud, se realizan las siguientes acciones en una transacción:
- Se quitan los datos existentes de
UserAccountManagementCluster
del socio desarrollador. - Los datos de la solicitud se analizan y se almacenan en el clúster de UserAccountManagementCluster actualizado.
En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
updatePublishStatus
Si, por algún motivo empresarial interno, no se publica ninguno de los clústeres, te recomendamos que actualices el estado de publicación a través de la API de updatePublishStatus. A continuación, explicamos por qué es importante:
- Proporcionar el estado en todas las situaciones, incluso cuando el contenido está publicado (STATUS == PUBLISHED), es fundamental para propagar los paneles que usan este estado explícito para transmitir el estado y otras métricas de tu integración.
- Si no se publica contenido pero el estado de integración no está roto (STATUS == NOT_PUBLISHED), Google puede evitar activar alertas en los paneles de estado de la app. Confirma que el contenido no se publicó debido a una situación prevista desde el punto de vista del proveedor.
- Ayuda a los desarrolladores a proporcionar estadísticas sobre cuándo se publican los datos no.
- Google puede usar los códigos de estado para sugerir al usuario que realice determinadas acciones en la app de modo que pueda ver el contenido de la app o superarlo.
La lista de códigos de estado de publicación aptos es la siguiente:
// 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 el contenido no se publica debido a que un usuario no accedió, te recomendamos que publiques la tarjeta de acceso. Si, por algún motivo, los proveedores no pueden publicar la tarjeta de acceso, recomendamos que llames a la API de updatePublishStatus con el código de estado 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
Esta API se usa para borrar el contenido de los clústeres de Recommendation.
Kotlin
client.deleteRecommendationClusters()
Java
client.deleteRecommendationClusters();
Cuando el servicio recibe la solicitud, quita los datos existentes de los clústeres de Recommendation. En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
deleteFeaturedCluster
Esta API se usa para borrar el contenido del clúster de Featured.
Kotlin
client.deleteFeaturedCluster()
Java
client.deleteFeaturedCluster();
Cuando el servicio recibe la solicitud, quita los datos existentes del clúster de Featured. En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
deleteContinuationCluster
Esta API se usa para borrar el contenido del clúster de Continuation.
Kotlin
client.deleteContinuationCluster()
Java
client.deleteContinuationCluster();
Cuando el servicio recibe la solicitud, quita los datos existentes del clúster de Continuation. En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
deleteUserManagementCluster
Esta API se usa para borrar el contenido del clúster de UserAccountManagement.
Kotlin
client.deleteUserManagementCluster()
Java
client.deleteUserManagementCluster();
Cuando el servicio recibe la solicitud, quita los datos existentes del clúster de UserAccountManagement. En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
deleteClusters
Esta API se usa para borrar el contenido de un tipo de clúster determinado.
Kotlin
client.deleteClusters( DeleteClustersRequest.Builder() .addClusterType(ClusterType.TYPE_FEATURED) .addClusterType(ClusterType.TYPE_RECOMMENDATION) ... .build())
Java
client.deleteClusters( new DeleteClustersRequest.Builder() .addClusterType(ClusterType.TYPE_FEATURED) .addClusterType(ClusterType.TYPE_RECOMMENDATION) ... .build());
Cuando el servicio recibe la solicitud, quita los datos existentes de todos los clústeres que coincidan con los tipos de clúster especificados. Los clientes pueden optar por pasar uno o varios tipos de clústeres. En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
Manejo de errores
Te recomendamos que escuches el resultado de la tarea de las APIs de publicación, de manera que se pueda realizar una acción de seguimiento para recuperar y volver a enviar una tarea con éxito.
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
}
}
}
});
El error se muestra como una AppEngageException
con la causa incluida como un código de error.
Código de error | Nota |
---|---|
SERVICE_NOT_FOUND |
El servicio no está disponible en el dispositivo determinado. |
SERVICE_NOT_AVAILABLE |
El servicio está disponible en el dispositivo determinado, pero no en el momento de la llamada (por ejemplo, está inhabilitado explícitamente). |
SERVICE_CALL_EXECUTION_FAILURE |
No se pudo ejecutar la tarea debido a problemas con los subprocesos. En este caso, se puede volver a intentar. |
SERVICE_CALL_PERMISSION_DENIED |
El llamador no tiene permiso para realizar la llamada de servicio. |
SERVICE_CALL_INVALID_ARGUMENT |
La solicitud contiene datos no válidos (por ejemplo, una cantidad de clústeres mayor que la permitida). |
SERVICE_CALL_INTERNAL |
Hay un error en el servicio. |
SERVICE_CALL_RESOURCE_EXHAUSTED |
La llamada de servicio se realiza con demasiada frecuencia. |
Paso 3: Controla los intents de transmisión
Además de realizar llamadas a las APIs de publicación de contenido a través de un trabajo, también se requiere configurar un BroadcastReceiver
para recibir la solicitud de publicación de contenido.
El objetivo de los intents de transmisión es principalmente reactivar apps y forzar la sincronización de datos. Los intents de transmisión no están diseñados para enviarse con mucha frecuencia. Solo se activan cuando el servicio de Engage determina que el contenido puede estar inactivo (por ejemplo, si es de hace una semana). De esa manera, será más probable que el usuario tenga una experiencia de contenido actualizada, incluso si la aplicación no se ejecutó durante un período prolongado.
El BroadcastReceiver
debe configurarse de las siguientes dos maneras:
- Registra de forma dinámica una instancia de la clase
BroadcastReceiver
conContext.registerReceiver()
. Esto permite la comunicación desde aplicaciones que aún están activas en la memoria.
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));
}
- Declara de forma estática una implementación con la etiqueta
<receiver>
en tu archivoAndroidManifest.xml
. Esto permite que la aplicación reciba intents de transmisión cuando no está en ejecución y que la aplicación publique el contenido.
<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>
El servicio enviará los siguientes intents:
com.google.android.engage.action.PUBLISH_RECOMMENDATION
Te recomendamos que inicies una llamada apublishRecommendationClusters
cuando recibas este intent.com.google.android.engage.action.PUBLISH_FEATURED
Te recomendamos que inicies una llamada apublishFeaturedCluster
cuando recibas este intent.com.google.android.engage.action.PUBLISH_CONTINUATION
Te recomendamos que inicies una llamada apublishContinuationCluster
cuando recibas este intent.
Flujo de trabajo de integración
Si deseas obtener una guía paso a paso para verificar la integración una vez que esta se complete, consulta Flujo de trabajo de integración para desarrolladores de Engage.
Preguntas frecuentes
Consulta Preguntas frecuentes sobre el SDK de Engage para ver preguntas frecuentes.
Contacto
Contactar engage-developers@google.com si hay preguntas durante el proceso de integración. Nuestro equipo te responderá lo antes posible.
Próximos pasos
Después de completar esta integración, sigue estos pasos:
- Envía un correo electrónico a engage-developers@google.com y adjunta el APK integrado que está listo para que Google lo pruebe.
- Google realizará una verificación y una revisión interna para garantizar que la integración funcione según lo previsto. En caso de que se necesiten cambios, Google se comunicará contigo con todos los detalles necesarios.
- Cuando se completen las pruebas y no se necesiten cambios, Google se comunicará contigo para notificarte que puedes comenzar a publicar el APK integrado y actualizado en Play Store.
- Después de que Google confirme que tu APK actualizado se publicó en Play Store, los clústeres de Recommendation, Featured y Continuation se publicarán y serán visibles para los usuarios.