Como otimizar o conteúdo contextual para o assistente

O Android 6.0 Marshmallow apresenta uma nova maneira para o usuário se envolver com apps por meio do assistente. O Assistente é uma janela de nível superior que o usuário pode ver para receber ações contextualmente relevantes para a atividade atual. Essas ações podem incluir links diretos para outros apps no dispositivo.

O usuário ativa o assistente tocando no botão Home e mantendo-o pressionado ou dizendo uma frase-chave. Em seguida, o sistema abre uma janela de nível superior que exibe ações contextualmente relevantes.

O Google app implementa a janela sobreposta do Assistente por meio de um recurso chamado "Now a um toque", que é compatível com a funcionalidade na plataforma do Android. O sistema permite que o usuário selecione um app assistivo, que recebe informações contextuais do seu app usando a API Assist do Android.

Este guia explica como os apps Android usam a API Assist para melhorar a experiência do usuário com o assistente. Para saber como criar um app de mídia que possa ser iniciado e controlado pelo Assistente, consulte Google Assistente e apps de mídia.

Usar o Assistente

A Figura 1 ilustra uma interação comum do usuário com o Assistente. Quando o usuário toca no botão Home e o mantém pressionado, os callbacks da API Assist são invocados no app de origem (etapa 1). O Assistente renderiza a janela sobreposta (etapas 2 e 3) e, em seguida, o usuário seleciona a ação a ser realizada. O assistente executa a ação selecionada, como disparar uma intent com um link direto para o app de restaurante (de destino) (etapa 4).

Figura 1. Exemplo de interação do Assistente com o recurso "Now a um toque" do Google app

O usuário pode configurar o Assistente selecionando Config. > Aplicativos > Aplicativos padrão > Assistente e entrada por voz. O usuário pode alterar as opções do sistema, como acessar o conteúdo da tela na forma de texto e acessar uma captura de tela, conforme mostrado na Figura 2.

Figura 2. Configurações de "Assistente e entrada por voz"

App de origem

Para garantir que seu app funcione com o assistente como uma fonte de informações para o usuário, siga as práticas recomendadas de acessibilidade. Essa seção descreve como oferecer mais informações para ajudar a melhorar a experiência do usuário com o Assistente, bem como cenários que precisam de tratamento especial, como visualizações personalizadas.

Compartilhar outras informações com o assistente

Além de textos e capturas de tela, seu app pode compartilhar outras informações com o assistente. Por exemplo, seu app de música pode passar as informações do álbum atual para que o Assistente sugira ações mais inteligentes e personalizadas para a atividade em andamento. As APIs Assist não oferecem controles de mídia. Para adicioná-los, consulte Google Assistente e apps de mídia.

Para transmitir outras informações ao Assistente, seu app oferece o contexto de aplicativo global registrando um listener de app e fornece informações específicas com callbacks da atividade, conforme mostrado na Figura 3:

Figura 3. Diagrama de sequência do ciclo de vida da API Assist

Para oferecer o contexto de aplicativo global, o app cria uma implementação de Application.OnProvideAssistDataListener e a registra usando registerOnProvideAssistDataListener(). Para fornecer informações contextuais específicas da atividade, a atividade modifica onProvideAssistData() e onProvideAssistContent(). Os dois métodos de atividade são chamados depois que o callback global opcional é invocado. Como os callbacks são executados na linha de execução principal, eles precisam ser concluídos imediatamente. Os callbacks são invocados apenas quando a atividade está em execução.

Fornecer contexto

Quando o usuário ativa o assistente, onProvideAssistData() é chamado para compilar um intent ACTION_ASSIST completo, com todo o contexto do app atual representado como uma instância de AssistStructure. Você pode modificar esse método e colocar o que quiser no pacote para ser exibido na parte EXTRA_ASSIST_CONTEXT da intent de assistência.

Descrever conteúdo

Seu app pode implementar onProvideAssistContent() para melhorar a experiência do usuário no assistente, fornecendo referências de conteúdo relacionadas à atividade atual. Você pode descrever o conteúdo do app usando o vocabulário comum definido pelo Schema.org por meio de um objeto JSON-LD. No exemplo abaixo, um app de música oferece dados estruturados para descrever o álbum que o usuário está visualizando no momento:

Kotlin

    override fun onProvideAssistContent(assistContent: AssistContent) {
        super.onProvideAssistContent(assistContent)

        val structuredJson: String = JSONObject()
                .put("@type", "MusicRecording")
                .put("@id", "https://example.com/music/recording")
                .put("name", "Album Title")
                .toString()

        assistContent.structuredData = structuredJson
    }
    

Java

    @Override
    public void onProvideAssistContent(AssistContent assistContent) {
      super.onProvideAssistContent(assistContent);

      String structuredJson = new JSONObject()
           .put("@type", "MusicRecording")
           .put("@id", "https://example.com/music/recording")
           .put("name", "Album Title")
           .toString();

      assistContent.setStructuredData(structuredJson);
    }
    

Você também pode melhorar a experiência do usuário por meio de implementações personalizadas de onProvideAssistContent(), que podem oferecer os seguintes benefícios:

Observação: os apps que usam uma implementação de seleção de texto personalizada provavelmente precisam implementar onProvideAssistContent() e chamar setClipData().

Implementação padrão

Se nenhum dos callbacks onProvideAssistData() e onProvideAssistContent() forem implementados, o sistema passará as informações coletadas automaticamente para o assistente, a menos que a janela atual esteja sinalizada como segura. Conforme mostrado na Figura 3, o sistema usa as implementações padrão de onProvideStructure() e onProvideVirtualStructure() para coletar texto e visualizar informações de hierarquia. Se a visualização implementar um desenho de texto personalizado, modifique onProvideStructure() para fornecer ao assistente o texto mostrado ao usuário chamando setText(CharSequence).

Na maioria dos casos, a implementação da compatibilidade com acessibilidade permite que o assistente colete as informações necessárias. Para implementar a compatibilidade com acessibilidade, observe as práticas recomendadas descritas em Como tornar aplicativos acessíveis, que incluem as seguintes:

Excluir visualizações do assistente

Para lidar com informações confidenciais, seu app pode excluir a visualização atual do assistente configurando o parâmetro de layout FLAG_SECURE do WindowManager. É preciso configurar FLAG_SECURE explicitamente para cada janela criada pela atividade, incluindo as caixas de diálogo. Seu app também pode usar setSecure() para excluir uma superfície do assistente. Não existe um mecanismo global (no app) para excluir todas as visualizações do assistente. Observe que FLAG_SECURE não faz com que os callbacks da API Assist parem de disparar. A atividade que usa FLAG_SECURE ainda pode fornecer informações de forma explícita ao assistente usando os callbacks descritos anteriormente neste guia.

Observação: para contas empresariais (Android for Work), o administrador pode desativar a coleta de dados do assistente para o perfil de trabalho usando o método setScreenCaptureDisabled() da API DevicePolicyManager.

Interações por voz

Os callbacks da API Assist também são invocados após a detecção da frase-chave. Para ver mais informações, consulte a documentação Ações por voz.

Considerações sobre a ordem Z

O assistente usa uma janela sobreposta leve, exibida na parte superior da atividade atual. Como o usuário pode ativar o Assistente a qualquer momento, não crie janelas permanentes de alerta do sistema que interfiram na janela sobreposta, como mostra a Figura 4.

Figura 4. Ordem Z da camada de assistência

Se seu app usa janelas de alerta do sistema, remova-as imediatamente. Se deixá-las na tela, a experiência do usuário será prejudicada.

App de destino

Em geral, o assistente usa as vantagens dos links diretos para encontrar apps de destino. Para tornar seu app um possível app de destino, adicione compatibilidade com links diretos. A correspondência entre o contexto atual do usuário e links diretos ou outras possíveis ações exibidas na janela sobreposta (conforme mostrado na etapa 3 da Figura 1) é específica para a implementação do Assistente. Por exemplo, o Google app usa links diretos e a Indexação de apps do Firebase para direcionar tráfego para apps de destino.

Implementar o próprio assistente

Você pode implementar o próprio assistente. Conforme mostrado na Figura 2, o usuário pode selecionar o app assistivo ativo. O app assistivo precisa fornecer uma implementação de VoiceInteractionSessionService e VoiceInteractionSession, conforme mostrado neste VoiceInteraction de exemplo. Isso também requer a permissão BIND_VOICE_INTERACTION. O assistente pode receber o texto e a hierarquia de visualização representada como uma instância de AssistStructure em onHandleAssist(). Ele recebe a captura de tela por meio do onHandleScreenshot().