Depois de criar atalhos, talvez seja necessário gerenciá-los durante o ciclo de vida do app. Por exemplo, talvez você queira otimizar o app determinando com que frequência os usuários concluem ações específicas com os atalhos. Em outro caso, você pode decidir desativar um atalho fixado para impedir que o app execute ações desatualizadas ou ausentes. Para atalhos referenciados em conversas, convém rastrear o uso para fornecer indicadores que melhorem a classificação de atalhos.
Nesta página, descrevemos essas e várias outras maneiras comuns de gerenciar seus atalhos.
Comportamento de atalhos
As seções a seguir contêm informações gerais sobre o comportamento dos 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 um 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 do app, mas pode ser diferente em outros apps de tela de início. Com o Google Assistente, os atalhos podem ser mostrados no Assistente ou iniciados por um comando de voz do usuário.
A classe LauncherApps fornece APIs para que os apps de inicialização 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.
As metas de compartilhamento são um subconjunto de atalhos dinâmicos que aparecem na linha de compartilhamento direto da página de compartilhamento do Android.
Ordem de exibição de atalhos
Quando o acesso rápido mostra os atalhos de um app, eles precisam aparecer na seguinte ordem:
- Atalhos estáticos: atalhos em que o método
isDeclaredInManifest()retornatrue. - Atalhos dinâmicos: atalhos em que o método
ShortcutInfo.isDynamic()retornatrue.
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 do atalho 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 ao último na ordem em que aparecem no arquivo shortcuts.xml. Para atalhos
dinâmicos, é possível atualizar as classificações de 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, o tempo para retorno, a frequência, a dica de classificação, o uso do app e a prioridade definida na
conversa associada a um atalho de compartilhamento. Os destinos de compartilhamento
criados com a API Sharing Shortcuts têm prioridade sobre os destinos 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 página de compartilhamento.
A maioria dos inicializadores mostra no máximo quatro atalhos. Para qualquer combinação de atalhos estáticos e 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 de forma programática três atalhos dinâmicos, a tela de início vai mostrar os dois primeiros atalhos estáticos e os dois atalhos dinâmicos 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. Para fazer isso, atribua várias intents, inicie uma atividade de outra ou defina 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 dele são destruídas quando um atalho estático
é iniciado. Se você não quiser esse comportamento, use uma atividade de trampolim,
que é uma atividade invisível que inicia outra, chamando finish
em um bloco de inicialização ou onCreate antes que o conteúdo do Compose seja definido:
No
AndroidManifest.xml file, inclua a atribuição de atributoandroid:taskAffinity=""na atividade trampolim.No arquivo de recursos de atalhos, faça referência à atividade trampolim na intent dentro do atalho estático.
Para mais informações sobre atividades trampolim, consulte Como iniciar uma atividade 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 o evento de atalho de maneira adequada usando onNewIntent().
Para saber mais sobre tarefas e flags de intent, consulte Tarefas e a backstack.
Atualização de atalhos
Cada ícone na tela de início do app pode conter, no máximo, um número de atalhos estáticos e dinâmicos
combinados que é 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 que o editor o remova como um
atalho dinâmico, o atalho fixado ainda fica visível e pode ser iniciado. Isso permite
que um app tenha mais de getMaxShortcutCountPerActivity atalhos.
Considere o exemplo a seguir, que pressupõe que o valor retornado por
getMaxShortcutCountPerActivity é 4:
- Um app de chat publica quatro atalhos dinâmicos, que representam as quatro conversas mais recentes: c1, c2, c3 e c4.
- O usuário fixa todos os quatro atalhos.
- Depois, o usuário inicia mais três conversas: c5, c6 e c7. O app 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 pode 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 levam 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.
- O app pode usar
updateShortcuts(Context, List)para atualizar qualquer um dos sete atalhos atuais. Por exemplo, você pode atualizar esse conjunto de atalhos quando os ícones dos participantes do chat mudarem. - Use os métodos
addDynamicShortcuts(Context, List)esetDynamicShortcuts(Context, List)para atualizar os atalhos com os mesmos IDs. No entanto, não é possível usá-los para atualizar atalhos fixos não dinâmicos, porque esses dois métodos tentam converter as listas de atalhos fornecidas em atalhos dinâmicos.
Não há limite para o número de atalhos que podem ser enviados para exibição em
apps assistivos, como o Google Assistente. Use o método pushDynamicShortcut
da biblioteca ShortcutManagerCompat do Jetpack para criar e atualizar
atalhos para uso em apps assistivos. 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 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, que indica 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,
você pode acompanhar quando os usuários concluem 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 assistivos, 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 para ações no app
que estão desatualizadas ou não existem 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. Também
é possível usar uma versão sobrecarregada desse método que aceita um
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ó possa chamá-los 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 do número específico de vezes que você pode chamar esses métodos é chamado de
limitação de taxa. Esse recurso impede que o ShortcutManagerCompat
consuma recursos do dispositivo em excesso.
Quando a limitação de taxa está ativa, isRateLimitingActive retorna verdadeiro.
No entanto, a limitação de taxa é redefinida durante determinados eventos. Assim, até mesmo apps em segundo plano
podem chamar métodos ShortcutManager até que o limite de taxa 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 inline em uma notificação.
Se você encontrar uma 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 your-user-id ]
Backup e restauração
Para permitir que os usuários façam backup e restauração no seu app ao
trocar de dispositivo, inclua a atribuição do atributo android:allowBackup="true"
no arquivo de manifesto do app. Se você oferece suporte a backup e restauração, lembre-se
dos seguintes pontos sobre os atalhos de apps:
- Os atalhos estáticos são republicados automaticamente, mas somente depois que o usuário reinstala o app em um novo dispositivo.
- Os atalhos dinâmicos não são armazenados em backup. Portanto, inclua uma lógica no app para republicá-los 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 dos ícones associados a eles. Portanto, salve as imagens dos atalhos fixados no app para que seja rápido restaurá-las em um novo dispositivo.
O snippet de código abaixo mostra como 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.getShortcuts(this, ShortcutManagerCompat.FLAG_MATCH_PINNED).isNotEmpty()) { // Pinned shortcuts are restored. Use updateShortcuts() to make // sure they contain up-to-date information. } } } // ... }