Mostrando conteúdo rápido no Android — Slices
Este artigo é uma continuação de outro que fala de App Actions, outra forma de mostrar rapidamente conteúdo ao usuário usando o Google Assistant:
Pensando que já fizemos uma forma rápida do usuário acessar as funcionalidades do app através das ações, porque não mostrar o conteúdo de forma mais direta e simples? Para isso, precisamos configurar um Android Slice. Que é uma forma dinâmica e interativa de mostrar o conteúdo do app diretamente no assistant, sem a necessidade de abrir o app efetivamente. Também é possível tomar algumas ações rápidas sem estar dentro de todo o contexto da aplicação.
Existem diversos templates de slices que podem ser usados conforme for ideal para o aplicativo. Além disso também é possível inserir dados de forma dinâmica através de uma conexão com servidor, controladores de entrada do usuário, LiveData, e outras diversas funcionalidades. Para saber mais sobre os Slices do Android, veja na documentação.
Instalar visualizador de slices
Antes de começar a criar os slices precisamos baixar um app que vai nos permitir visualizar esses componentes.
Primeiro, é preciso baixar o app na página de releases do Slice Viewer. Em seguida, basta instalar o APK no dispositivo. Se preferir use diretamente o comando do adb
: adb install -r -t slice-viewer.apk
Criar provedor de slices
O próximo passo agora é criar um SliceProvider
que pode ser feito diretamente pelo Android Studio: Arquivo > Novo > Outros > Slice Provider
. Lembrando também que é necessário registrar esse provedor no AndroidManifest.xml
:
No caso do RecipeSliceProvider
ele possui apenas um atributo que é uma lista mutável de receitas e, a cada nova ação acionada pelo usuário que mostra o assistant, é feito uma busca no Firestore com o id obtido na uri e, quando retornado sucesso é mostrado um conteúdo resumido da receita no slice vinculado. A decisão de usar uma lista é porque podem existir inúmeros slices aparecendo juntos em uma sessão do assistant. Por isso ficamos com diversas referências que são associadas por seus identificadores de forma que cada slice mostra o conteúdo correto da receita que corresponde.
Neste provedor temos alguns pontos de atenção: onCreateSliceProvider
é usado para iniciar qualquer objeto que seja necessário e retornar true
caso o provedor tenha sido criado com sucesso, caso contrário, retorna false
.
A implementação deonMapIntentToUri
é necessária apenas no caso em que o app precisa obter e mapear as requisições de url e converter urls comuns em content uri. No caso desse app, o mapeamento do slice foi feito diretamente via um content uri, então não foi necessária toda essa implementação.
O método onBindSlice
é responsável por construir o slice e vincular os dados necessários. Também é neste método que fazemos o mapeamento do conteúdo, através do path
do sliceUri
.
Em onSlicePinned
o slice foi atrelado a um serviço e está prestes a ser exibido pro usuário. Nesse momento é hora de buscar os dados do servidor, sobrescrever para algum observable, etc. Ao final, quando obter os dados necessários, basta chamar context.contentResolver.notifyChanged(sliceUri, null)
para que seja atualizado o onBindSlice
com o novo conteúdo.
Para o caso exclusivo deste app e para facilitar o desenvolvimento, foi usado o SDK puro do Firestore para obtenção dos dados, de forma que foram usados apenas callbacks sem interação com live data, e nenhuma outra forma de observable.
Por fim, onSliceUnpinned
é a hora de remover os observers e fazer qualquer limpeza para evitar vazamentos de memória. No caso do app de receitas, é feito apenas a limpeza dos dados dentro da lista recipes
.
Usar templates para slices
Os Slices são construídos através de um sistema de lista (ListBuilder
) que pode ter diferentes tipos de formato de linhas. O primeiro é o cabeçalho (HeaderBuilder
) que possuem as informações principais do slice e também é o conteúdo mostrado quando o slice está no modo de visualização compacto. Outro formato é a linha em si (RowBuilder
) para um conteúdo mais simples, e podendo ter uma ou mais ações rápidas atreladas. De forma semelhante tem o formato de grid (GridBuilder
) que mostra o conteúdo em diferentes colunas dentro da mesma linha. Também é possível adicionar uma barra de progresso ou um slider através do RangeBuilder
. Para mais informações sobre templates dos slices veja na documentação.
Para o app de receitas usei o HeaderBuilder
para mostrar o nome da receita no modo reduzido do slice e nas outras partes, foi usado o RowBuilder
por ser um conteúdo mais simples e único, precisando apenas de linhas mesmo. Contudo, foi configurado três tipos de slices: um para ser exibido enquanto os dados são carregados, outro para quando a receita foi retornada e outro para o caso de ter retornado algum erro ou não ter sido encontrada a receita.
Para os slices é importante que apareça alguma informação instantânea para o usuário mesmo ainda não tendo todos os dados a serem mostrados .. por isso, foi criado o slice para mostrar que o conteúdo está sendo carregado.
Para o carregamento da imagem da receita foi utilizada a biblioteca Glide que transforma uma url de imagem em um bitmap no android e, com isso foi gerado o IconImage
necessário para ser inserido no slice.
Por fim, repare que em diversos momentos foi configurado também uma primaryAction
que é uma SliceAction
na qual possui informações de intents e pending intents.
Testar slice no dispositivo
Para testar no Slice Viewer instalado anteriormente, é necessário criar uma nova configuração de execução no Android Studio. Nomeie-a como preferir e em nas opções de lançamento (Launch Options) selecione o modo URL e na url coloque slice-content://<application_id>/path
de acordo com o que você configurou no SliceProvider dentro do AndroidManifest.xml
. No caso do app de receitas, também foi necessário adicionar o parâmetro recipe
porque precisamos dele para saber qual a receita mostrar pro usuário. Após adicionado, basta rodar essa nova configuração.
Configurar ação para usar o slice
Finalmente, vamos configurar o arquivo actions.xml
para mostrar o slice criado. Para isso, basta adicionar um novo fullfiment
dentro da ação com fullfilmentMode="actions.fullfilment.SLICE
e o urlTemplate
de acordo com o que ficou no AndroidManifest
.
Pronto! Agora já está configurado para abrir o slice direto no Google Assistant. Para testar essa parte agora, basta abrir o Android App Actions Test Tool novamente e, se tiver um preview já criado, clique em Update Preview para que a ferramenta possa atualizar suas informações com as alterações feitas em actions.xml
.
Considerações finais
Implementar ações e slices para o app pode ser algo bem interessante que ajuda muito no engajamento e na interação do usuário. Contudo, muitas coisas ainda estão em fase experimental, por isso algumas questões ainda podem se alterar e tem muito a ser aprimorado.
De qualquer forma, é uma funcionalidade incrível que vale a pena testar e aprender pois está cada vez mais comum obtermos conteúdo através de assistentes virtuais e ter isso a favor do nosso aplicativo pode ser um alto ganho de usabilidade e negócio.
O código completo do projeto abordado neste artigo pode ser encontrado no Github.