Esta guía contiene instrucciones para que los desarrolladores compartan datos de suscripción y derechos de la app con Google TV mediante el SDK de Engage. Los usuarios pueden encontrar el contenido al que tienen derecho y habilitar Google TV para que les proporcione recomendaciones de contenido muy relevantes directamente en las experiencias de Google TV en TV, dispositivos móviles y tablets.
Requisitos previos
Es necesario incorporar el feed de acciones de medios antes de que puedas usar la API de derechos del dispositivo. Si aún no lo hiciste, completa el proceso de incorporación del feed de acciones de medios.
Trabajo previo
Completa las instrucciones de trabajo previo en la guía de introducción.
- Publica información de suscripción en los siguientes eventos:
- El usuario accede a tu app.
- El usuario cambia entre perfiles (si se admiten perfiles).
- El usuario compra una suscripción nueva.
- El usuario actualiza una suscripción existente.
- Vence la suscripción del usuario.
Integración
En esta sección, se proporcionan los ejemplos de código y las instrucciones necesarios para implementar SubscriptionEntity y administrar varios tipos de suscripción.
Suscripción de nivel común
Para los usuarios con suscripciones básicas a los servicios del proveedor de contenido multimedia, por ejemplo, un servicio que tiene un nivel de suscripción que otorga acceso a todo el contenido pagado, proporciona estos detalles esenciales:
SubscriptionType: Indica claramente el plan de suscripción específico que tiene el usuario.SUBSCRIPTION_TYPE_ACTIVE: El usuario tiene una suscripción pagada activa.SUBSCRIPTION_TYPE_ACTIVE_TRIAL: El usuario tiene una suscripción de prueba.SUBSCRIPTION_TYPE_INACTIVE: El usuario tiene una cuenta, pero no tiene una suscripción ni una prueba activas.
ExpirationTimeMillis: Es el tiempo opcional en milisegundos. Especifica cuándo vencerá la suscripción.ProviderPackageName: Especifica el nombre del paquete de la app que controla la suscripción.
Ejemplo del feed de muestra del proveedor de contenido multimedia.
"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
}
En el siguiente ejemplo, se crea un SubscriptionEntity para un usuario:
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()
Suscripción Premium
Si la app ofrece paquetes de suscripción Premium de varios niveles, que incluyen contenido o funciones expandidos más allá del nivel común, represéntalo agregando uno o más derechos a la suscripción.
Este derecho tiene los siguientes campos:
Identifier: Es la cadena de identificador obligatoria para este derecho. Debe coincidir con uno de los identificadores de derechos (ten en cuenta que no es el campo de ID) que se proporcionan en el feed del proveedor de contenido multimedia publicado en Google TV.Name: Es información auxiliar y se usa para la coincidencia de derechos. Si bien es opcional, proporcionar un nombre de derecho legible por humanos mejora la comprensión de los derechos de los usuarios para los desarrolladores y los equipos de asistencia. Por ejemplo: Sling Orange.ExpirationTimeMillis: De manera opcional, especifica la hora de vencimiento en milisegundos para este derecho, si difiere de la hora de vencimiento de la suscripción. De forma predeterminada, el derecho vencerá con el vencimiento de la suscripción.
Para el siguiente fragmento de feed de muestra del proveedor de contenido multimedia:
"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"
}
En el siguiente ejemplo, se crea un SubscriptionEntity para un usuario suscrito:
// 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()
Suscripción al paquete de servicios vinculados
Si bien las suscripciones suelen pertenecer al proveedor de contenido multimedia de la app de origen, se puede atribuir una suscripción a un paquete de servicios vinculados si se especifica el nombre del paquete de servicios vinculados dentro de la suscripción.
En el siguiente ejemplo de código, se muestra cómo crear una suscripción de usuario.
// 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()
Además, si el usuario tiene otra suscripción a un servicio subsidiario, agrega otra suscripción y establece el nombre del paquete de servicios vinculados según corresponda.
// 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()
De manera opcional, también puedes agregar derechos a una suscripción de servicio vinculada.
Proporciona un conjunto de suscripciones
Ejecuta el trabajo de publicación de contenido mientras la app está en primer plano.
Usa el método publishSubscriptionCluster() de la
AppEngagePublishClient clase para publicar un objeto SubscriptionCluster.
Asegúrate de inicializar el cliente y verificar la disponibilidad del servicio como se describe en la guía de introducción.
client.publishSubscription(
PublishSubscriptionRequest.Builder()
.setAccountProfile(accountProfile)
.setSubscription(subscription)
.build()
)
Usa setSubscription() para verificar que el usuario solo deba tener una suscripción al servicio.
Usa addLinkedSubscription() o addLinkedSubscriptions(), que aceptan una lista de suscripciones vinculadas, para permitir que el usuario tenga cero o más suscripciones vinculadas.
Cuando el servicio recibe la solicitud, se crea una entrada nueva y la entrada anterior se borra automáticamente después de 60 días. El sistema siempre usa la entrada más reciente. En caso de error, se rechaza la solicitud completa y se mantiene el estado existente.
Mantén actualizada la suscripción
Para proporcionar actualizaciones inmediatas cuando se producen cambios, llama a
publishSubscriptionClustercada vez que cambie el estado de suscripción de un usuario, como la activación, la desactivación, las actualizaciones y los cambios a versiones inferiores.Para proporcionar una validación periódica para la precisión continua, llama a
publishSubscriptionClusteral menos una vez al mes.Para borrar los datos de Engage, borra manualmente los datos de un usuario del servidor de Google TV antes del período de retención estándar de 60 días, usa el método
client.deleteClusters. Esto borra todos los datos existentes de Engage para el perfil de la cuenta o para toda la cuenta, según elDeleteReasonproporcionado.En el siguiente fragmento de código, se muestra cómo quitar una suscripción de usuario:
// If the user logs out from your media app, you must make the following call // to remove subscription and other Engage data from the current // google TV device. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile(accountProfile) .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT) .build() )En el siguiente fragmento de código, se muestra la eliminación de la suscripción del usuario cuando este revoca el consentimiento:
// If the user revokes the consent to share across device, make the call // to remove subscription and other Engage data from all google // TV devices. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile(accountProfile) .setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT) .build() )En el siguiente código, se muestra cómo quitar los datos de suscripción cuando se borra el perfil del usuario.
// If the user delete a specific profile, you must make the following call // to remove subscription data and other Engage data. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile(accountProfile) .setReason(DeleteReason.DELETE_REASON_ACCOUNT_PROFILE_DELETION) .build() )
Prueba
En esta sección, se proporciona una guía paso a paso para probar la implementación de la suscripción. Verifica la precisión de los datos y la funcionalidad adecuada antes del lanzamiento.
Lista de tareas de integración de publicación
La publicación debe realizarse cuando la app está en primer plano y el usuario interactúa activamente con ella.
Publica cuando ocurra lo siguiente:
- El usuario accede por primera vez.
- El usuario cambia de perfil (si se admiten perfiles).
- El usuario compra una suscripción nueva.
- El usuario actualiza la suscripción.
- Vence la suscripción del usuario.
Comprueba si la app llama correctamente a las APIs de
isServiceAvailableypublishClustersen logcat, en los eventos de publicación.Verifica que los datos sean visibles en la app de verificación. La app de verificación debe mostrar la suscripción como una fila independiente. Cuando se invoca la API de publicación, los datos deben aparecer en la app de verificación.
Ve a la app y realiza cada una de las siguientes acciones:
- Accede.
- Cambia entre perfiles (si se admite).
- Compra una suscripción nueva.
- Actualiza una suscripción existente.
- Haz que venza la suscripción.
Verifica la integración
Para probar tu integración, usa la app de verificación.
- Para cada uno de los eventos, verifica si la app invocó la API de
publishSubscription. Verifica los datos publicados en la app de verificación. Verifica que todo esté en verde en la app de verificación. Si toda la información de la entidad es correcta, se muestra una marca de verificación verde "Todo bien" en todas las entidades.
Figura 1. Suscripción exitosa Los problemas también se destacan en la app de verificación.
Figura 2:Suscripción sin éxito Para ver los problemas en la suscripción agrupada, usa el control remoto de la TV para enfocarte en esa suscripción agrupada específica y haz clic para ver los problemas. Es posible que primero debas enfocarte en la fila y moverte hacia la derecha para encontrar la tarjeta de suscripción agrupada. Los problemas se destacan en rojo, como se muestra en la Figura 3. Además, usa el control remoto para desplazarte hacia abajo y ver los problemas en los derechos dentro de la suscripción agrupada.
Figura 3.Errores de suscripción Para ver los problemas en el derecho, usa el control remoto de la TV para enfocarte en ese derecho específico y haz clic para ver los problemas. Los problemas se destacan en rojo.
Figura 4.Detalles del error de suscripción