book_path: /distribute/other-docs/_book.yaml project_path: /distribute/other-docs/_project.yaml
Este guia contém instruções para desenvolvedores compartilharem dados de assinatura e direitos do app com o Google TV usando o SDK Engage. Os usuários podem encontrar conteúdo a que têm direito e permitir que o Google TV ofereça recomendações de conteúdo altamente relevantes diretamente nas experiências do Google TV em TVs, dispositivos móveis e tablets.
Pré-requisitos
É necessário integrar o feed de ações de mídia antes de usar a API de direitos do dispositivo. Se ainda não tiver feito isso, conclua o processo de integração do feed de ações de mídia.
Pré-trabalho
Siga as instruções de Pré-trabalho no guia para iniciantes.
- Publicar informações de assinatura nos seguintes eventos:
- O usuário faz login no app.
- O usuário alterna entre perfis (se eles forem compatíveis).
- O usuário compra uma nova assinatura.
- O usuário faz upgrade de uma assinatura.
- A assinatura do usuário expira.
Integração
Esta seção fornece os exemplos de código e as instruções necessárias para implementar o SubscriptionEntity e gerenciar vários tipos de assinatura.
Assinatura de nível comum
Para usuários com assinaturas básicas de serviços de provedores de mídia, por exemplo, um serviço que tem um nível de assinatura que concede acesso a todo o conteúdo pago, forneça estes detalhes essenciais:
SubscriptionType: indique claramente o plano de assinatura específico que o usuário tem.SUBSCRIPTION_TYPE_ACTIVE: o usuário tem uma assinatura paga ativa.SUBSCRIPTION_TYPE_ACTIVE_TRIAL: o usuário tem uma assinatura de teste.SUBSCRIPTION_TYPE_INACTIVE: o usuário tem uma conta, mas não tem uma assinatura ou um teste ativo.
ExpirationTimeMillis: tempo opcional em milissegundos. Especifique quando a assinatura vai expirar.ProviderPackageName: especifique o nome do pacote do app que processa a assinatura.
Exemplo do feed de provedor de mídia de amostra.
"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
}
O exemplo a seguir cria uma SubscriptionEntity para um usuário:
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()
Assinatura Premium
Se o app oferecer pacotes de assinatura premium de vários níveis, incluindo conteúdo ou recursos expandidos além do nível comum, represente isso adicionando um ou mais direitos à assinatura.
Esse direito tem os seguintes campos:
Identifier: string de identificador obrigatória para este direito. Ele precisa corresponder a um dos identificadores de direitos (não é o campo ID) fornecidos no feed do provedor de mídia publicado no Google TV.Name: são informações auxiliares usadas para correspondência de direitos. Embora seja opcional, fornecer um nome de direito legível para humanos melhora a compreensão dos direitos do usuário para desenvolvedores e equipes de suporte. Por exemplo: Sling Orange.ExpirationTimeMillis: especifique opcionalmente o prazo de validade em milissegundos para esse direito, se ele for diferente do prazo de validade da assinatura. Por padrão, o direito expira com a expiração da assinatura.
Para o snippet de feed de provedor de mídia de exemplo a seguir:
"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"
}
O exemplo a seguir cria uma SubscriptionEntity para um usuário inscrito:
// 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()
Assinatura do pacote de serviços vinculados
Embora as assinaturas normalmente pertençam ao provedor de mídia do app de origem, uma assinatura pode ser atribuída a um pacote de serviços vinculados especificando o nome do pacote de serviços vinculados na assinatura.
O exemplo de código a seguir demonstra como criar uma assinatura de usuário.
// 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()
Além disso, se o usuário tiver outra assinatura de um serviço subsidiário, adicione outra assinatura e defina o nome do pacote de serviço vinculado de acordo.
// 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()
Se quiser, adicione direitos a uma assinatura de serviço vinculada também.
Fornecer conjunto de assinaturas
Execute o trabalho de publicação de conteúdo enquanto o app está em primeiro plano.
Use o método publishSubscriptionCluster() da classe AppEngagePublishClient para publicar um objeto SubscriptionCluster.
Inicialize o cliente e verifique a disponibilidade do serviço conforme descrito no Guia de início rápido.
client.publishSubscription(
PublishSubscriptionRequest.Builder()
.setAccountProfile(accountProfile)
.setSubscription(subscription)
.build()
)
Use setSubscription() para verificar se o usuário tem apenas uma assinatura do serviço.
Use addLinkedSubscription() ou addLinkedSubscriptions(), que aceitam uma lista
de assinaturas vinculadas, para permitir que o usuário tenha zero ou mais assinaturas
vinculadas.
Quando o serviço recebe a solicitação, uma nova entrada é criada e a antiga é excluída automaticamente após 60 dias. O sistema sempre usa a entrada mais recente. Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.
Manter a assinatura atualizada
Para fornecer atualizações imediatas após as mudanças, chame
publishSubscriptionClustersempre que o estado da assinatura de um usuário mudar como ativação, desativação, upgrades e downgrades.Para fornecer validação regular da acurácia contínua, chame
publishSubscriptionClusterpelo menos uma vez por mês.Para excluir os dados de descoberta de vídeo, exclua manualmente os dados de um usuário do servidor do Google TV antes do período de retenção padrão de 60 dias usando o método
client.deleteClusters. Isso exclui todos os dados de descoberta de vídeo do perfil da conta ou de toda a conta, dependendo doDeleteReasonespecificado.O snippet de código a seguir mostra como remover uma assinatura de usuário:
// If the user logs out from your media app, you must make the following call // to remove subscription and other video discovery data from the current // google TV device. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile(accountProfile) .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT) .build() )O snippet de código a seguir demonstra a remoção da assinatura do usuário quando ele revoga o consentimento:
// If the user revokes the consent to share across device, make the call // to remove subscription and other video discovery data from all google // TV devices. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile(accountProfile) .setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT) .build() )O código a seguir demonstra como remover dados de assinatura na exclusão do perfil do usuário.
// If the user delete a specific profile, you must make the following call // to remove subscription data and other video discovery data. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile(accountProfile) .setReason(DeleteReason.DELETE_REASON_ACCOUNT_PROFILE_DELETION) .build() )
Teste
Esta seção fornece um guia detalhado para testar a implementação de assinaturas. Verifique a precisão dos dados e a funcionalidade adequada antes do lançamento.
Lista de verificação de publicação da integração
A publicação deve acontecer quando o app estiver em primeiro plano e o usuário interagindo ativamente com ele.
Publicar quando:
- O usuário faz login pela primeira vez.
- O usuário muda de perfil (se houver suporte para perfis).
- O usuário compra uma nova assinatura.
- O usuário faz upgrade da assinatura.
- A assinatura do usuário expira.
Verifique se o app está chamando corretamente as APIs
isServiceAvailable()epublishClusters()no logcat, nos eventos de publicação.Confira se os dados estão visíveis no app de verificação. Ele mostra a assinatura como uma linha separada. Quando a API de publicação é invocada, os dados aparecem no app de verificação.
Acesse o app e faça cada uma das seguintes ações:
- Faça login.
- Alternar entre perfis (se compatível).
- Compre uma nova assinatura.
- Fazer upgrade de uma assinatura.
- Expirar a assinatura.
Verificar a integração
Para testar sua integração, use o app de verificação.
- Para cada um dos eventos, verifique se o app invocou a API
publishSubscription. Verifique os dados publicados no app de verificação. Confira se tudo está verde no app de verificação Se todas as informações da entidade estiverem corretas, um tique verde "Tudo certo" vai aparecer em todas as entidades.
Figura 1. Assinatura feita com sucesso Os problemas também são destacados no app de verificação
Figura 2.Assinatura sem sucesso Para ver os problemas na assinatura do pacote, use o controle remoto da TV para focar na assinatura específica e clique para conferir os problemas. Talvez seja necessário primeiro focar na linha e mover para a direita para encontrar o card "Assinatura agrupada". Os problemas são destacados em vermelho, como mostrado na Figura 3. Use também o controle remoto para rolar para baixo e ver problemas nos direitos da assinatura agrupada.
Figura 3. Erros de assinaturaPara ver os problemas no direito, use o controle remoto da TV para focar nesse direito específico e clique para ver os problemas. Os problemas são destacados em vermelho.
Figura 4.Detalhes do erro de assinatura