Gerenciar atalhos

Depois de criar atalhos, pode ser necessário gerenciá-los durante o ciclo de vida do app. Por exemplo, você pode querer otimizar o app determinando a frequência com que os usuários realizam ações específicas com os atalhos. Em outro caso, você pode desativar um atalho fixado para evitar que o app execute ações desatualizadas ou ausentes. Para atalhos referenciados em conversas, talvez seja interessante acompanhar o uso para fornecer indicadores que melhorem o ranking de atalhos.

Nesta página, descrevemos essas e outras formas comuns de gerenciar seus atalhos.

Comportamento de atalhos

As seções a seguir contêm informações gerais sobre o comportamento de atalhos, incluindo visibilidade, ordem de exibição e classificações.

Visibilidade de atalhos

Os atalhos estáticos e dinâmicos aparecem em uma tela de início ou assistente compatível quando o usuário realiza um gesto ou comando de voz específico. Em telas de início compatíveis, o gesto consiste em tocar e pressionar o ícone na tela de início do app, mas o gesto pode ser diferente em outros apps na tela de início. Com o Google Assistente, os atalhos podem ser exibidos no Assistente ou iniciados com um comando de voz do usuário.

A classe LauncherApps fornece APIs para apps na tela de início acessarem atalhos.

Como os atalhos fixados aparecem na própria tela de início, eles estão sempre visíveis. Um atalho fixado só é removido da tela de início nas seguintes situações:

  • Removido pelo usuário.
  • O app associado ao atalho foi desinstalado.
  • Para limpar os dados do app, o usuário acessa Configurações > Apps e notificações, seleciona o app e toca em Armazenamento > Limpar armazenamento.

Os alvos de compartilhamento são um subconjunto de atalhos dinâmicos que aparecem na linha de compartilhamento direto da planilha de compartilhamento do Android.

Um Android Sharesheet
Figura 1. O Android Sharesheet. Os destinos de compartilhamento direto aparecem na primeira linha, seguidos pelos apps classificados e pelas listas de apps.

Ordem de exibição de atalhos

Quando a tela de início exibe os atalhos de um app, eles precisam aparecer na seguinte ordem:

  1. Atalhos estáticos: atalhos cujo método isDeclaredInManifest() retorna true.
  2. Atalhos dinâmicos: atalhos cujo método ShortcutInfo.isDynamic() retorna true.

Em cada tipo de atalho (estático e dinâmico), os atalhos são classificados em ordem crescente de classificação, de acordo com ShortcutInfo.getRank. O Google Assistente também considera a classificação ao determinar os atalhos contextuais que serão exibidos aos usuários.

As classificações são números inteiros sequenciais não negativos. Os atalhos estáticos são classificados do primeiro ao último na ordem em que aparecem no arquivo shortcuts.xml. Para atalhos dinâmicos, é possível atualizar as classificações dos atalhos existentes ao chamar updateShortcuts(Context, List), addDynamicShortcuts(Context, List), pushDynamicShortcut(Context, ShortcutInfoCompat) ou setDynamicShortcuts(Context, List).

A ordem dos destinos de compartilhamento é baseada em vários fatores, incluindo histórico de usuários, tempo para retorno, frequência, dica de classificação, uso do app e a prioridade definida na conversa associada a um compartilhamento rápido. Os alvos de compartilhamento criados com a API Sharing Shortcuts têm prioridade em relação aos alvos de compartilhamento produzidos pelo ChooserTargetService, que foi descontinuado no Android 11. No Android 12 e versões mais recentes, os destinos de compartilhamento gerados pelo ChooserTargetService descontinuado não vão mais aparecer na tela de compartilhamento.

A maioria das telas de início mostra no máximo quatro atalhos. Para qualquer combinação de atalhos estáticos e dinâmicos definidos, a tela de início mostra um máximo de dois atalhos estáticos e dois dinâmicos. Por exemplo, se você definir quatro atalhos estáticos e criar três atalhos dinâmicos de forma programática, a tela de início vai mostrar os dois primeiros atalhos estáticos e os dois dinâmicos com melhor classificação.

Gerenciar várias intents e atividades

Se você quiser que seu app execute várias operações quando o usuário ativar um atalho, é possível configurá-lo para acionar atividades sucessivas. Você pode fazer isso atribuindo vários intents, iniciando uma atividade a partir de outra ou definindo flags de intent, dependendo do tipo de atalho.

Iniciar uma atividade a partir de outra

Os atalhos estáticos não podem ter flags de intent personalizadas. A primeira intent de um atalho estático sempre tem Intent.FLAG_ACTIVITY_NEW_TASK e Intent.FLAG_ACTIVITY_CLEAR_TASK definidos. Isso significa que, quando o app está em execução, todas as atividades existentes nele são destruídas quando um atalho estático é iniciado. Se você não quiser esse comportamento, use uma atividade trampolim, ou seja, uma atividade invisível que inicia outra atividade, chamando finish em um bloco de inicialização ou onCreate antes de definir o conteúdo do Compose:

  1. No AndroidManifest.xml file, inclua a atribuição de atributo android:taskAffinity="" na atividade trampolim.

  2. No arquivo de recursos de atalhos, faça referência à atividade trampolim na intent no atalho estático.

Para mais informações sobre atividades trampolim, consulte Como iniciar uma atividade a partir de outra.

Definir sinalizações de intent

É possível publicar atalhos dinâmicos com qualquer conjunto de flags Intent. De preferência, especifique a combinação de Intent.FLAG_ACTIVITY_SINGLE_TOP e Intent.FLAG_ACTIVITY_CLEAR_TOP na intent do atalho. Isso garante que, se o ComponentActivity já estiver ativo, ele será trazido para o primeiro plano e reutilizado sem ser destruído, permitindo que a arquitetura de atividade única processe normalmente o evento de atalho por onNewIntent().

Para saber mais sobre tarefas e flags de intent, consulte Tarefas e a backstack.

Atualização de atalhos

O ícone na tela de início de cada app pode conter, no máximo, um número de atalhos estáticos e dinâmicos combinados igual ao valor retornado por getMaxShortcutCountPerActivity. Não há limite para o número de atalhos fixados que um app pode criar.

Quando um atalho dinâmico é fixado, mesmo se removido como atalho dinâmico pelo editor, o atalho fixado continua visível e pode ser iniciado. Isso permite que um app tenha mais do que o número de getMaxShortcutCountPerActivity de atalhos.

Considere o exemplo a seguir, que pressupõe que o valor retornado por getMaxShortcutCountPerActivity seja 4:

  1. Um app de chat publica quatro atalhos dinâmicos que representam as quatro conversas mais recentes: c1, c2, c3 e c4.
  2. O usuário fixa todos os quatro atalhos.
  3. Mais tarde, o usuário inicia outras três conversas: c5, c6 e c7. O app do editor republica os atalhos dinâmicos. A nova lista de atalhos dinâmicos é: c4, c5, c6 e c7.

O app precisa remover c1, c2 e c3, porque não é possível mostrar mais de quatro atalhos dinâmicos. No entanto, c1, c2 e c3 ainda são atalhos fixados que o usuário pode acessar e iniciar.

O usuário pode acessar um total de sete atalhos que vinculam a atividades no app do editor. Isso ocorre porque o total inclui o número máximo de atalhos e os três atalhos fixados.

  1. O app pode usar updateShortcuts(Context, List) para atualizar qualquer um dos sete atalhos existentes. Por exemplo, você pode atualizar esse conjunto de atalhos quando os ícones de chat mudarem.
  2. Você pode usar os métodos addDynamicShortcuts(Context, List) e setDynamicShortcuts(Context, List) para atualizar atalhos existentes com os mesmos IDs. No entanto, eles não podem ser usados para atualizar atalhos fixados e não dinâmicos, porque esses dois métodos tentam converter a lista especificada de atalhos em atalhos dinâmicos.

Não há limite para o número de atalhos que podem ser enviados para exibição em apps de assistência, como o Google Assistente. Use o método pushDynamicShortcut da biblioteca ShortcutManagerCompat do Jetpack para criar e atualizar atalhos para uso em apps de assistência. Além disso, adicione a biblioteca de integração do Google Shortcuts ao seu app para que os links dinâmicos possam aparecer no Google Assistente.

Para saber mais sobre as diretrizes para atalhos de apps, incluindo a atualização deles, consulte Práticas recomendadas para atalhos.

Processar as mudanças de localidade do sistema

Os apps precisam atualizar os atalhos dinâmicos e fixados quando recebem a transmissão Intent.ACTION_LOCALE_CHANGED indicando uma mudança na localidade do sistema.

Rastrear o uso de atalhos

Para determinar as situações em que os atalhos estáticos e dinâmicos aparecem, a tela de início examina o histórico de ativação dos atalhos. Para atalhos estáticos, é possível acompanhar quando os usuários realizam ações específicas no seu app chamando o método reportShortcutUsed e passando para ele o ID de um atalho quando qualquer um dos seguintes eventos ocorrer:

  • O usuário selecionar o atalho com o ID fornecido.
  • O usuário completa manualmente a ação correspondente ao mesmo atalho no app.

Seu app rastreia o uso de atalhos dinâmicos chamando o método pushDynamicShortcut e transmitindo para ele o ID do atalho quando ocorre um evento relevante. O envio do uso de atalhos dinâmicos com esse método permite que apps assistentes, como o Google Assistente, sugiram atalhos relevantes aos usuários. Como o método pushDynamicShortcut informa o uso quando chamado, não chame o método reportShortcutUsed para os mesmos atalhos.

Para atalhos relacionados a conversas, é importante acompanhar o uso de mensagens enviadas e recebidas. Para mais detalhes, consulte as práticas recomendadas para pessoas e conversas.

Desativar atalhos

Como o app e os usuários podem fixar atalhos na tela de início do dispositivo, é possível que esses atalhos fixados direcionem os usuários a ações no app que estejam desatualizadas ou não existam mais. Para gerenciar essa situação, você pode desativar os atalhos que não quer que os usuários selecionem chamando disableShortcuts, que remove os atalhos especificados da lista de atalhos estáticos e dinâmicos e desativa as cópias fixadas desses atalhos. Você também pode usar uma versão sobrecarregada desse método que aceita um CharSequence como uma mensagem de erro personalizada. Essa mensagem de erro vai aparecer quando os usuários tentarem iniciar um atalho desativado.

Limitação de taxa

Ao usar os métodos setDynamicShortcuts, addDynamicShortcuts ou updateShortcuts, talvez você só possa chamar esses métodos um número específico de vezes em um app em segundo plano, ou seja, um app sem atividades ou serviços em primeiro plano. O limite para o número específico de vezes que você pode chamar esses métodos é chamado de limitação de taxa. Esse recurso evita que o ShortcutManagerCompat consuma recursos do dispositivo em excesso.

Quando a limitação de taxa está ativa, isRateLimitingActive retorna "true". No entanto, a limitação de taxa é redefinida durante determinados eventos, de modo que até mesmo apps em segundo plano podem chamar métodos ShortcutManager até que o limite seja atingido novamente. Esses eventos incluem:

  • Um app aparece em primeiro plano.
  • A localidade do sistema muda.
  • O usuário executa a ação de resposta in-line em uma notificação.

Se você encontrar a limitação de taxa durante o desenvolvimento ou teste, selecione Opções do desenvolvedor > Redefinir limitação de taxa do ShortcutManager nas configurações do dispositivo ou insira o seguinte comando em adb:

$ adb shell cmd shortcut reset-throttling [ --user <var>your-user-id</var> ]

Backup e restauração

Você pode permitir que os usuários realizem operações de backup e restauração no app ao trocar de dispositivo incluindo a atribuição do atributo android:allowBackup="true" no arquivo de manifesto do app. Se você oferecer suporte a backup e restauração, lembre-se dos seguintes pontos sobre os atalhos de apps:

  • Os atalhos estáticos são publicados novamente de forma automática, mas somente depois que o app é reinstalado pelo usuário em um novo dispositivo.
  • Os atalhos dinâmicos não são armazenados em backup. Por isso, inclua uma lógica no app para publicá-los novamente quando um usuário abrir o app em um novo dispositivo.
  • Os atalhos fixados são restaurados automaticamente na tela de início do dispositivo, mas o sistema não faz backup de ícones associados a atalhos fixados. Por isso, salve as imagens dos atalhos fixados no seu app para que seja rápido restaurá-los em um novo dispositivo.

O snippet de código a seguir mostra qual é a melhor forma de restaurar os atalhos dinâmicos do app e como verificar se os atalhos fixados foram preservados:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (ShortcutManagerCompat.getDynamicShortcuts(this).isEmpty()) {
            // Application restored. Re-publish dynamic shortcuts.
            if (ShortcutManagerCompat.getPinnedShortcuts(this).isNotEmpty()) {
                // Pinned shortcuts are restored. Use updateShortcuts() to make
                // sure they contain up-to-date information.
            }

        }
    }
    // ...
}