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 decidir desativar um atalho fixado para evitar que o app execute ações desatualizadas ou ausentes. Para atalhos referenciados em conversas, você pode acompanhar o uso para fornecer indicadores que melhoram a classificação de atalhos.

Esta página descreve essas e outras maneiras comuns de gerenciar 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 os atalhos 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 é tocar e pressionar o ícone na tela de início, mas pode ser diferente em outros apps. Com o Google Assistente, os atalhos podem ser mostrados no Assistente ou iniciados por um comando de voz do usuário.

A classe LauncherApps oferece APIs para que apps na tela de início acessem 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.
  • O usuário limpa os dados de um app acessando Configurações > Apps e notificações, selecionando o app e tocando em Armazenamento > Limpar armazenamento.

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

Captura de tela do Android Sharesheet
Figura 1. O Android Sharesheet. Os alvos de compartilhamento direto aparecem na primeira linha, seguidos pelos aplicativos classificados e, em seguida, pelas listas de aplicativos.

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 de maior classificação, de acordo com ShortcutInfo.getRank. O Google Assistente também considera a classificação dos atalhos ao determinar os atalhos contextuais que serão mostrados aos usuários.

As classificações são números inteiros sequenciais não negativos. Os atalhos estáticos são classificados do primeiro para o último na ordem em que aparecem no arquivo shortcuts.xml. Para atalhos dinâmicos, você pode 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 o histórico do usuário, tempo para retorno, frequência, dica de classificação, uso do app e a prioridade definida na conversa associada a um atalho de compartilhamento. Os alvos de compartilhamento criados usando a API Share Shortcuts são priorizados 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 alvos de compartilhamento gerados pelo ChooserTargetService descontinuado não vão mais aparecer na planilha de compartilhamento.

A maioria das telas de início exibe no máximo quatro atalhos. Para qualquer combinação de atalhos estáticos e atalhos dinâmicos definidos, a tela de início mostra no máximo 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 mais bem classificados.

Gerenciar várias intents e atividades

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

Atribuir várias intents

Ao criar um atalho com ShortcutInfoCompat.Builder, você pode usar setIntents() em vez de setIntent(). Ao chamar setIntents(), é possível iniciar várias atividades no seu app quando o usuário seleciona um atalho, colocando todas as atividades da lista, exceto a última, na pilha de retorno. Se o usuário tocar no botão "Voltar" do dispositivo, ele verá outra atividade no app em vez de retornar à tela de início do dispositivo.

Iniciar uma atividade a partir de outra

Os atalhos estáticos não podem ter sinalizações de intent personalizadas. A primeira intent de um atalho estático sempre tem Intent.FLAG_ACTIVITY_NEW_TASK e Intent.FLAG_ACTIVITY_CLEAR_TASK set. Isso significa que, quando o app estiver em execução, todas as atividades atuais vão ser destruídas quando um atalho estático for iniciado. Se não quiser esse comportamento, use uma atividade trampolim, uma atividade invisível que inicia outra, em Activity.onCreate(Bundle) que chama Activity.finish():

  1. No arquivo AndroidManifest.xml, 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 saber mais sobre as atividades trampolim, consulte Como iniciar uma atividade de outra.

Definir sinalizações de intent

É possível publicar atalhos dinâmicos com qualquer conjunto de sinalizações Intent. De preferência, especifique Intent.FLAG_ACTIVITY_CLEAR_TASK com suas outras flags. Caso contrário, se você tentar iniciar outra tarefa enquanto o app estiver em execução, a atividade de destino poderá não aparecer.

Para saber mais sobre tarefas e sinalizações de intent, consulte Tarefas e a backstack.

Atualização de atalhos

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

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

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

  1. Um app de chat publica quatro atalhos dinâmicos, representando 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 três conversas adicionais: c5, c6 e c7. O app do editor publica novamente 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 dos apps semelhantes mudam.
  2. Você pode usar os métodos addDynamicShortcuts(Context, List) e setDynamicShortcuts(Context, List) para atualizar atalhos existentes com os mesmos IDs. No entanto, não é possível usá-los para atualizar atalhos fixados não dinâmicos, porque esses dois métodos tentam converter as listas fornecidas de atalhos em atalhos dinâmicos.

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

Para saber mais sobre as diretrizes de atalhos de apps, incluindo a atualização de atalhos, 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. No caso de atalhos estáticos, você pode acompanhar quando os usuários realizam ações específicas no app, chamando o método reportShortcutUsed() e transmitindo o ID de um atalho quando um dos seguintes eventos ocorrer:

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

Seu app rastreia o uso de atalhos dinâmicos chamando o método pushDynamicShortcut() e transmitindo o ID do atalho quando um evento relevante ocorre. O envio do uso de atalhos dinâmicos com esse método permite que apps assistentes, como o Google Assistente, sugiram atalhos relevantes para os 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 rastrear 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 dele 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 uma CharSequence como uma mensagem de erro personalizada. Essa mensagem de erro aparece quando os usuários tentam iniciar qualquer atalho desativado.

Limitação de taxa

Ao usar os métodos setDynamicShortcuts(), addDynamicShortcuts() ou updateShortcuts(), talvez você só consiga 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 impede que 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. Assim, mesmo os apps em segundo plano podem chamar métodos ShortcutManager até que a limitação de taxa seja atingida novamente. Esses eventos incluem o seguinte:

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

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

$ adb shell cmd shortcut reset-throttling [ --user your-user-id ]

Backup e restauração

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

  • Os atalhos estáticos são republicados automaticamente, mas somente depois que o usuário reinstalar o app em um novo dispositivo.
  • Os atalhos dinâmicos não têm backup. Portanto, 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. Portanto, salve as imagens dos atalhos fixados no app para facilitar a restauração em um novo dispositivo.

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

Kotlin

class MyMainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (ShortcutManagerCompat.dynamicShortcuts.size == 0) {
            // Application restored. Re-publish dynamic shortcuts.
            if (ShortcutManagerCompat.pinnedShortcuts.size > 0) {
                // Pinned shortcuts are restored. Use updateShortcuts() to make
                // sure they contain up-to-date information.
            }

        }
    }
    // ...
}

Java

public class MainActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (ShortcutManagerCompat.getDynamicShortcuts().size() == 0) {
            // Application restored. Re-publish dynamic shortcuts.
            if (ShortcutManagerCompat.getPinnedShortcuts().size() > 0) {
                // Pinned shortcuts are restored. Use pdateShortcuts() to make
                // sure they contain up-to-date information.
            }
        }
    }
    // ...
}