SDK Engage Listen: instruções técnicas da integração de terceiros

O Google está criando uma plataforma no dispositivo que organiza os apps dos usuários por categoria e possibilita uma nova experiência imersiva para consumo e descoberta de conteúdo personalizado de apps. Essa experiência em tela cheia oferece aos parceiros dos desenvolvedores uma oportunidade de mostrar o melhor conteúdo avançado em um canal dedicado fora do app.

Este guia contém instruções para que os parceiros dos desenvolvedores integrem conteúdo de áudio, usando o SDK Engage para preencher essa nova área e as plataformas do Google.

Detalhe de integração

Terminologia

Essa integração inclui os três tipos de cluster a seguir: recomendação, continuação e destaque.

  • Os clusters de recomendação mostram sugestões personalizadas de conteúdo para leitura de um parceiro de desenvolvedor específico.

    As recomendações têm a seguinte estrutura:

    • Cluster de recomendação: uma visualização de interface que contém um grupo de recomendações do mesmo parceiro do desenvolvedor.

      Figura 1. Interface do Entertainment Space mostrando um cluster de recomendação de um único parceiro.
    • Entidade: um objeto que representa um único item em um cluster. Uma entidade pode ser uma playlist, um audiolivro, um podcast e muito mais. Consulte a seção Fornecer dados da entidade para conferir uma lista dos tipos de entidade aceitas.

      Figura 2. Interface do Entertainment Space mostrando uma única entidade dentro do cluster de recomendação de um parceiro.
  • O cluster de continuação mostra conteúdo de áudio com que os usuários interagiram recentemente de vários parceiros de desenvolvedores em um único grupo de interfaces. Cada parceiro de desenvolvedor pode transmitir no máximo 10 entidades no cluster de continuação.

    Figura 3. A interface do Entertainment Space mostrando um cluster de continuação com recomendações de livros inacabados de vários parceiros (apenas uma recomendação está visível no momento).
  • O cluster de destaque mostra uma seleção de itens de vários parceiros de desenvolvimento em um único grupo de interfaces. Há um único cluster de destaque, exibido perto da parte de cima da interface, com um posicionamento prioritário acima de todos os clusters de recomendação. Cada parceiro de desenvolvedor pode transmitir até 10 entidades no cluster de destaque.

    Figura 4. A interface do Entertainment Space mostrando um cluster de destaque com recomendações de vários parceiros (apenas uma recomendação está visível no momento).

Pré-trabalho

Nível mínimo da API: 19

Adicione a biblioteca com.google.android.play:engage ao app:

dependencies {
    // Make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.engage:engage-core:1.4.0'
}

Resumo

O design é baseado na implementação de um serviço vinculado.

Os dados que um cliente pode publicar estão sujeitos aos seguintes limites para diferentes tipos de clusters:

Tipo de cluster Limites de cluster Limites máximos de entidades em um cluster
Clusters de recomendação No máximo 5 No máximo 50
Cluster de continuação No máximo 1 No máximo 10
Cluster de destaque No máximo 1 No máximo 10

Etapa 1: fornecer dados da entidade

O SDK definiu entidades diferentes para representar cada tipo de item. Oferecemos suporte às seguintes entidades na categoria "Ouvir":

  1. MusicAlbumEntity
  2. MusicArtistEntity
  3. MusicTrackEntity
  4. MusicVideoEntity
  5. PlaylistEntity
  6. PodcastSeriesEntity
  7. PodcastEpisodeEntity
  8. LiveRadioStationEntity
  9. AudiobookEntity

As tabelas abaixo descrevem os atributos e os requisitos disponíveis para cada tipo.

MusicAlbumEntity

O objeto MusicAlbumEntity representa um álbum de música (por exemplo, Midnights de Taylor Swift).

Atributo Requisito Observações
Nome Obrigatório O título do álbum.
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Info page uri Obrigatório

O link direto para o app do provedor para mais detalhes sobre o álbum.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Artists Obrigatório Lista de artistas do álbum.
Playback uri Opcional

Um link direto que começa a tocar o álbum no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Songs count Opcional O número de músicas no álbum.
Genres Opcional Lista de gêneros no álbum.
Album Format Opcional

ÁLBUM (inclui LP e LP duplo)

EP

SINGLE

Mixtape

Music labels Opcional Lista de gravadoras associadas ao álbum.
Downloaded on Device Opcional Booleano que indica se o álbum de música foi transferido por download para o dispositivo.
Explicit Opcional

Um booleano que indica se o conteúdo é explícito ou não

Itens que contêm material explícito ou que têm um aviso aos pais precisam ser definidos como TRUE. Os itens explícitos aparecem com uma tag "E".

Data de lançamento Opcional A data de lançamento do álbum em milissegundos de época.
Duração Opcional A duração do álbum em milissegundos.
Last engagement time Opcional

Recomendado para itens no cluster de continuação. Pode ser usado para classificação.

Em milissegundos de época

Progress percentage complete Opcional

Recomendado para itens no cluster de continuação.

Número inteiro entre 0 e 100

MusicArtistEntity

O objeto MusicArtistEntity representa um artista da música (por exemplo, Adele).

Atributo Requisito Observações
Nome Obrigatório Nome do artista da música.
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Info page uri Obrigatório

O link direto para o app do provedor com detalhes sobre o artista da música.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Playback uri Opcional

O link direto que começa a tocar as músicas do artista no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Last engagement time Opcional

Recomendado para itens no cluster de continuação. Pode ser usado para classificação.

Em milissegundos de época

MusicTrackEntity

O objeto MusicTrackEntity representa uma música (por exemplo, Yellow do Coldplay).

Atributo Requisito Observações
Nome Obrigatório Título da música.
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Playback uri Obrigatório

Um link direto que começa a tocar a música no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Info page uri Opcional

Um link direto para o app do provedor com detalhes sobre a música.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Duration Opcional Duração da faixa em milissegundos.
Album Opcional O nome do álbum ao qual a música pertence.
Artists Obrigatório Lista de artistas da música.
Downloaded on Device Opcional Booleano que indica se a faixa de música foi transferida por download para o dispositivo.
Explicit Opcional

Um booleano que indica se o conteúdo é explícito ou não

Itens que contêm material explícito ou que têm um aviso aos pais precisam ser definidos como TRUE. Os itens explícitos aparecem com uma tag "E".

Last engagement time Opcional

Recomendado para itens no cluster de continuação. Pode ser usado para classificação.

Em milissegundos de época

Progress percentage complete Opcional

Recomendado para itens no cluster de continuação.

Número inteiro entre 0 e 100

MusicVideoEntity

O objeto MusicVideoEntity representa um vídeo de música (por exemplo, The Weeknd - Take My Breath (videoclipe oficial)).

Atributo Requisito Observações
Nome Obrigatório Título do videoclipe.
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Playback uri Obrigatório

Um link direto que inicia a reprodução do videoclipe no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Info page uri Opcional

Um link direto para o app do provedor com detalhes sobre o videoclipe.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Duração Opcional A duração do vídeo em milissegundos.
View count Opcional É o número de visualizações do vídeo no formato de texto livre.
Artists Opcional Lista de artistas do videoclipe.
Content rating Opcional Lista de classificações de conteúdo da faixa.
Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Downloaded on Device Opcional Booleano que indica se o vídeo de música foi transferido por download para o dispositivo.
Explicit Opcional

Um booleano que indica se o conteúdo é explícito ou não

Itens que contêm material explícito ou que têm um aviso aos pais precisam ser definidos como TRUE. Os itens explícitos aparecem com uma tag "E".

Last engagement time Opcional

Recomendado para itens no cluster de continuação. Pode ser usado para classificação.

Em milissegundos de época

Progress percentage complete Opcional

Recomendado para itens no cluster de continuação.

Número inteiro entre 0 e 100

PlaylistEntity

O objeto PlaylistEntity representa uma playlist de músicas (por exemplo, a playlist de top 10 dos EUA).

Atributo Requisito Observações
Nome Obrigatório Título da playlist.
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Playback uri Obrigatório

Um link direto que começa a tocar a playlist de músicas no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Info page uri Opcional

Um link direto para o app do provedor com detalhes sobre a playlist de músicas.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Duração Opcional A duração da playlist em milissegundos.
Songs count Opcional O número de músicas na playlist.
Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Downloaded on Device Opcional Booleano que indica se a playlist foi transferida por download para o dispositivo.
Explicit Opcional

Um booleano que indica se o conteúdo é explícito ou não

Itens que contêm material explícito ou que têm um aviso aos pais precisam ser definidos como TRUE. Os itens explícitos aparecem com uma tag "E".

Last engagement time Opcional

Recomendado para itens no cluster de continuação. Pode ser usado para classificação.

Em milissegundos de época

Progress percentage complete Opcional

Recomendado para itens no cluster de continuação.

Número inteiro entre 0 e 100

PodcastSeriesEntity

O objeto PodcastSeriesEntity representa uma série de podcasts (por exemplo, This American Life).

Atributo Requisito Observações
Nome Obrigatório Título da série de podcasts.
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Info page uri Obrigatório

Um link direto para o app do provedor com detalhes sobre a série de podcasts.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Playback uri Opcional

Um link direto que começa a tocar a série de podcasts no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Episode count Opcional O número de episódios da série de podcasts.
Production name Opcional O nome da produção da série de podcasts.
Hosts Opcional Lista de apresentadores da série de podcasts.
Gêneros Opcional Lista de gêneros da série de podcasts.
Download feito no dispositivo Opcional Booleano que indica se o podcast foi transferido por download para o dispositivo.
Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Explicit Opcional

Um booleano que indica se o conteúdo é explícito ou não

Itens que contêm material explícito ou que têm um aviso aos pais precisam ser definidos como TRUE. Os itens explícitos aparecem com uma tag "E".

Last engagement time Opcional

Recomendado para itens no cluster de continuação. Pode ser usado para classificação.

Em milissegundos de época

PodcastEpisodeEntity

O objeto PodcastEpisodeEntity representa uma série de podcasts (por exemplo, Spark Bird, episódio 754: This American Life).

Atributo Requisito Observações
Nome Obrigatório Título do episódio do podcast.
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Playback uri Obrigatório

Um link direto que começa a tocar o episódio de podcast no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Production series title Obrigatório É o nome da série de podcast a que o episódio pertence.
Duration Obrigatório A duração do episódio de podcast em milissegundos.
Publish Date Obrigatório Data de publicação do podcast (em milissegundos de época)
Info page uri Opcional

Um link direto para o app do provedor com detalhes sobre o episódio do podcast.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Production name Opcional O nome da produção da série de podcasts.
Episode index Opcional O índice do episódio da série (o primeiro índice é 1).
Hosts Opcional Lista de apresentadores do episódio de podcast.
Gêneros Opcional Lista de gêneros do episódio de podcast.
Download feito no dispositivo Opcional Booleano que indica se o episódio de podcast foi transferido por download para o dispositivo.
Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Video Podcast Opcional Booleano que indica se o episódio de podcast tem conteúdo de vídeo
Explicit Opcional

Um booleano que indica se o conteúdo é explícito ou não

Itens que contêm material explícito ou que têm um aviso aos pais precisam ser definidos como TRUE. Os itens explícitos aparecem com uma tag "E".

Listen Next Type Opcional

Recomendado para itens no cluster de continuação

TYPE_CONTINUE: retoma um item de áudio não concluído.

TYPE_NEXT: continua em um novo episódio da série.

TYPE_NEW: lançado recentemente.

Last engagement time Opcional

Recomendado para itens no cluster de continuação. Pode ser usado para classificação.

Em milissegundos de época

Progress percentage complete Opcional

Recomendado para itens no cluster de continuação.

Número inteiro entre 0 e 100

LiveRadioStationEntity

O objeto LiveRadioStationEntity representa uma estação de rádio ativa (por exemplo, 98.1 The Breeze).

Atributo Requisito Observações
Nome Obrigatório Título da estação de rádio ao vivo.
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Playback uri Obrigatório

Um link direto que começa a tocar a estação de rádio no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Info page uri Opcional

Um link direto para o app do provedor com detalhes sobre a estação de rádio.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Frequency Opcional É a frequência em que a estação de rádio é transmitida (por exemplo, "FM 98.1").
Show title Opcional O programa que está tocando na estação de rádio.
Hosts Opcional Lista de apresentadores da estação de rádio.
Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Last engagement time Opcional

Recomendado para itens no cluster de continuação. Pode ser usado para classificação.

Em milissegundos de época

AudiobookEntity

O objeto AudiobookEntity representa um audiolivro. Por exemplo, o audiolivro Minha História, de Michelle Obama.

Atributo Requisito Observações
Nome Obrigatório
Poster images Obrigatório É necessário fornecer pelo menos uma imagem. Consulte as orientações em Especificações de imagem.
Author Obrigatório É necessário fornecer pelo menos um nome de autor.
Narrator Obrigatório Pelo menos um nome de narrador deve ser fornecido.
Action link uri Obrigatório

O link direto para o app do provedor do audiolivro.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Publish date Opcional Em milissegundos de época, se fornecido.
Descrição Opcional Precisa ter até 200 caracteres, se fornecido.
Preço Opcional Texto livre
Duração Opcional Precisa ser um valor positivo, se informado.
Genre Opcional Lista de gêneros associados ao livro.
Series name Opcional Nome da série a que o audiolivro pertence (por exemplo, Harry Potter).
Series unit index Opcional O índice do audiolivro da série, em que 1 é o primeiro audiolivro da série. Por exemplo, se Harry Potter e o Prisioneiro de Azkaban for o terceiro livro da série, defina como 3.
Continue book type Opcional

TYPE_CONTINUE: retoma um livro não concluído.

TYPE_NEXT: continua em um novo livro da série.

TYPE_NEW: lançado recentemente.

Last Engagement Time Obrigatório sob certas condições

Precisa ser fornecido quando o item estiver no cluster de continuação.

Em milissegundos de época.

Progress Percentage Complete Obrigatório sob certas condições

Precisa ser fornecido quando o item estiver no cluster de continuação.

Audiolivros *recém-adquiridos* podem fazer parte do cluster de leitura contínua.

O valor precisa ser maior que 0 e menor que 100.

DisplayTimeWindow: define uma janela de tempo para que um conteúdo seja mostrado na plataforma
Carimbo de data/hora do início Opcional

Carimbo de data/hora da época depois da qual o conteúdo será mostrado na plataforma.

Se não for definido, o conteúdo poderá ser mostrado na plataforma.

Em milissegundos de época.

Carimbo de data/hora do término Opcional

Carimbo de data/hora da época depois da qual o conteúdo não será mais mostrado na plataforma.

Se não for definido, o conteúdo poderá ser mostrado na plataforma.

Em milissegundos de época.

Especificações da imagem

Consulte abaixo as especificações necessárias para recursos de imagem:

Proporção Requisito Mínimo de pixels Pixels recomendados
Quadrada (1 x 1) Obrigatório 300 x 300 1.200 x 1.200
Paisagem (1,91 x 1) Opcional 600 x 314 1.200 x 628
Retrato (4 x 5) Opcional 480 x 600 960 x 1.200

Formatos de arquivo

PNG, JPG, GIF estático, WebP

Tamanho máximo do arquivo

5.120 KB

Recomendações adicionais

  • Área de segurança da imagem: posicione o conteúdo importante no centro da imagem, ocupando 80% do espaço.

Exemplos

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

Etapa 2: fornecer dados do cluster

É recomendável executar o job de publicação de conteúdo em segundo plano (por exemplo, usando o WorkManager) e programado com frequência ou por evento (por exemplo, toda vez que o usuário abrir o app ou adicionar algo ao carrinho).

AppEngagePublishClient é responsável pela publicação de clusters. As seguintes APIs estão disponíveis no cliente:

  • isServiceAvailable
  • publishRecommendationClusters
  • publishFeaturedCluster
  • publishContinuationCluster
  • publishUserAccountManagementRequest
  • updatePublishStatus
  • deleteRecommendationsClusters
  • deleteFeaturedCluster
  • deleteContinuationCluster
  • deleteUserManagementCluster
  • deleteClusters

isServiceAvailable

Essa API é usada para conferir se o serviço está disponível para integração e se o conteúdo pode ser apresentado no 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

Essa API é usada para publicar uma 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());

Quando o serviço recebe a solicitação, as ações abaixo ocorrem em uma transação:

  • Os dados do RecommendationCluster do parceiro do desenvolvedor são removidos.
  • Os dados da solicitação são analisados e armazenados no cluster de recomendação atualizado.

Em caso de erro, o pedido inteiro é rejeitado e o estado atual é mantido.

publishFeaturedCluster

Essa API é usada para publicar uma 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());

Quando o serviço recebe a solicitação, as ações abaixo ocorrem em uma transação:

  • Os dados do FeaturedCluster do parceiro do desenvolvedor são removidos.
  • Os dados da solicitação são analisados e armazenados no cluster de destaque atualizado.

Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

publishContinuationCluster

Essa API é usada para publicar um 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())

Quando o serviço recebe a solicitação, as ações abaixo ocorrem em uma transação:

  • Os dados do ContinuationCluster do parceiro do desenvolvedor são removidos.
  • Os dados da solicitação são analisados e armazenados no cluster de continuação atualizado.

Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

publishUserAccountManagementRequest

Essa API é usada para publicar um card de login. A ação de login direciona os usuários à página de login do app para que ele possa publicar ou oferecer conteúdo mais personalizado.

Os metadados abaixo fazem parte do card de login:

Atributo Requisito Descrição
Action Uri Obrigatório Link direto para a ação (ou seja, leva à página de login do app)
Imagem Opcional: se não for fornecido, o título precisa ser fornecido

Imagem mostrada no card

Imagens com proporção de 16 x 9 e resolução de 1.264 x 712

Título Opcional: se não for fornecido, a imagem precisará ser fornecida Título do card
Action Text Opcional Texto mostrado no CTA (por exemplo, "Fazer login")
Subtitle Opcional Subtítulo opcional do card

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

Quando o serviço recebe o pedido, as seguintes ações ocorrem em uma transação:

  • Os dados do UserAccountManagementCluster do parceiro do desenvolvedor são removidos.
  • Os dados do pedido são analisados e armazenados no cluster UserAccountManagementCluster atualizado.

Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

updatePublishStatus

Se, por qualquer motivo interno, nenhum dos clusters for publicado, é altamente recomendável atualizar o status de publicação usando a API updatePublishStatus. Isso é importante pelos seguintes motivos:

  • Informar o status em todos os casos possíveis, mesmo quando o conteúdo é publicado (STATUS == PUBLISHED), é fundamental para preencher painéis que usam o status explícito para transmitir informações de integridade e outras métricas da integração.
  • Se nenhum conteúdo for publicado, mas o status da integração não estiver corrompido (STATUS == NOT_PUBLISHED), o Google poderá evitar o acionamento de alertas nos painéis de integridade do app. Isso confirma que o conteúdo não foi publicado devido a uma situação esperada pelo provedor.
  • Ajuda os desenvolvedores a oferecer insights sobre quando os dados foram publicados ou não.
  • O Google pode usar os códigos de status para incentivar o usuário a executar ações específicas no app, como acessar o conteúdo ou resolver o problema.

Lista de códigos de status de publicação que podem ser usados:

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

Se o conteúdo não for publicado porque o usuário não estava conectado, o Google recomenda publicar o card de login. Se, por algum motivo, os provedores não conseguirem publicar o card de login, recomendamos chamar a API updatePublishStatus usando o código de status 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

Essa API é usada para excluir o conteúdo dos clusters de recomendação.

Kotlin


client.deleteRecommendationClusters()

Java


client.deleteRecommendationClusters();

Quando o serviço recebe o pedido, ele remove os dados atuais dos clusters de recomendação. Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

deleteFeaturedCluster

Essa API é usada para excluir o conteúdo do cluster de destaque.

Kotlin


client.deleteFeaturedCluster()

Java


client.deleteFeaturedCluster();

Quando o serviço recebe o pedido, ele remove os dados atuais do cluster de destaque. Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

deleteContinuationCluster

Essa API é usada para excluir o conteúdo do cluster de continuação.

Kotlin


client.deleteContinuationCluster()

Java


client.deleteContinuationCluster();

Quando o serviço recebe o pedido, ele remove os dados atuais do cluster de continuação. Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

deleteUserManagementCluster

Essa API é usada para excluir o conteúdo do cluster UserAccountManagement.

Kotlin


client.deleteUserManagementCluster()

Java


client.deleteUserManagementCluster();

Quando o serviço recebe o pedido, ele remove os dados atuais do cluster UserAccountManagement. Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

deleteClusters

Essa API é usada para excluir o conteúdo de determinado tipo de cluster.

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

Quando o serviço recebe a solicitação, ele remove os dados de todos os clusters que correspondem aos tipos especificados. Os clientes podem transmitir um ou vários tipos de clusters. Em caso de erro, a solicitação inteira é rejeitada e o estado existente é mantido.

Tratamento de erros

É recomendável detectar o resultado da tarefa nas APIs de publicação. Com isso, uma ação de acompanhamento pode ser realizada para recuperar e reenviar uma tarefa bem-sucedida.

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

O erro é retornado como AppEngageException e a causa é incluída como um código de erro.

Código do erro Observação
SERVICE_NOT_FOUND O serviço não está disponível no dispositivo.
SERVICE_NOT_AVAILABLE O serviço está disponível no dispositivo em questão, mas não no momento da chamada (por exemplo, está desativado).
SERVICE_CALL_EXECUTION_FAILURE A execução da tarefa falhou devido a problemas de linha de execução. Nesse caso, ela pode ser repetida.
SERVICE_CALL_PERMISSION_DENIED O autor da chamada não tem permissão para fazer a chamada de serviço.
SERVICE_CALL_INVALID_ARGUMENT A solicitação contém dados inválidos (por exemplo, tem um número de clusters maior do que o permitido).
SERVICE_CALL_INTERNAL Há um erro no serviço.
SERVICE_CALL_RESOURCE_EXHAUSTED A chamada de serviço é feita com muita frequência.

Etapa 3: processar intents de transmissão

Além de fazer chamadas de API de conteúdo de publicação usando um job, também é necessário configurar um BroadcastReceiver para receber a solicitação de publicação de conteúdo.

O objetivo principal das intents de transmissão é reativar o app e forçar a sincronização de dados. As intents de transmissão não são projetadas para envio muito frequente. Elas só são acionadas quando o serviço do Engage determina que o conteúdo pode estar desatualizado (por exemplo, é de uma semana atrás). Dessa forma, há mais confiança de que o usuário poderá ter uma nova experiência de conteúdo, mesmo que o aplicativo não tenha sido executado por um longo período.

O BroadcastReceiver precisa ser configurado de duas maneiras:

  • Registre dinamicamente uma instância da classe BroadcastReceiver usando Context.registerReceiver(). Isso permite a comunicação de aplicativos que ainda estão ativos na memória.
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));

}
  • Declare estaticamente uma implementação com a tag <receiver> no arquivo AndroidManifest.xml. Isso permite que o aplicativo receba intents de transmissão quando não está em execução e também permite que ele publique o conteúdo.
<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>

As intents a seguir serão enviadas pelo serviço:

  • com.google.android.engage.action.PUBLISH_RECOMMENDATION Recomendamos que você inicie uma chamada publishRecommendationClusters ao receber essa intent.
  • com.google.android.engage.action.PUBLISH_FEATURED Recomendamos que você inicie uma chamada publishFeaturedCluster ao receber essa intent.
  • com.google.android.engage.action.PUBLISH_CONTINUATION Recomendamos que você inicie uma chamada publishContinuationCluster ao receber essa intent.

Fluxo de trabalho de integração

Para acessar um guia explicativo sobre como verificar a integração após a conclusão, consulte Fluxo de trabalho de integração de desenvolvedor.

Perguntas frequentes

Consulte as Perguntas frequentes sobre o SDK Engage para acessar as perguntas frequentes.

Contato

Entre em contato com engagement-developers@google.com se tiver perguntas durante o processo de integração. Nossa equipe vai responder assim que possível.

Próximas etapas

Depois de concluir essa integração, as próximas etapas serão as seguintes:

  • Envie um e-mail para engage-developers@google.com e anexe seu APK integrado pronto para ser testado pelo Google.
  • O Google vai realizar uma verificação e revisão internamente para garantir que a integração funcione conforme o esperado. Se for necessário fazer mudanças, o Google entrará em contato informando todos os detalhes necessários.
  • Quando o teste estiver concluído e nenhuma mudança for necessária, o Google entrará em contato para informar que você pode começar a publicar o APK atualizado e integrado na Play Store.
  • Depois que o Google confirmar a publicação do APK atualizado na Play Store, seus clusters de recomendação, destaque e continuação serão publicados e ficarão visíveis aos usuários.