As Configurações rápidas são blocos mostrados no painel de Configurações rápidas,
que representam ações que os usuários podem tocar para concluir tarefas recorrentes rapidamente.
Seu app pode fornecer um bloco personalizado aos usuários usando a classe TileService
e um objeto Tile para acompanhar o estado do bloco. Por exemplo,
você pode criar um bloco que permita aos usuários ativar ou desativar uma VPN fornecida pelo
provedor de VPN do app.
Decidir quando criar um bloco
Recomendamos criar blocos para funcionalidades específicas que os usuários vão acessar com frequência ou que precisam de acesso rápido (ou ambos). Os blocos mais eficazes são aqueles que combinam essas duas qualidades, oferecendo acesso rápido a ações realizadas com frequência.
Por exemplo, você pode criar um bloco para um app de fitness que permita aos usuários iniciar rapidamente uma sessão de treino. No entanto, não recomendamos criar um bloco para o mesmo app que permita aos usuários revisar todo o histórico de treinos.
Para melhorar a facilidade de descoberta e de uso do bloco, recomendamos evitar algumas práticas:
Evite usar blocos para iniciar um app. Use um atalho de app ou uma tela de início padrão.
Evite usar blocos para ações únicas do usuário. Use um atalho de app ou uma notificação.
Evite criar blocos demais. Recomendamos no máximo dois por app. Use um atalho de app.
Evite usar blocos que mostram informações, mas não são interativos para os usuários. Use uma notificação ou um widget.
Criar o bloco
Para criar um bloco, primeiro crie um ícone de bloco apropriado e, em seguida,
crie e declare o TileService no arquivo de manifesto do app.
O exemplo de Configurações rápidas mostra como criar e gerenciar um bloco.
Criar seu ícone personalizado
Você precisa fornecer um ícone personalizado, que é exibido no bloco no painel de
Configurações rápidas. Você vai adicionar esse ícone ao declarar o TileService,
descrito na próxima seção. O ícone precisa ser branco sólido com um
plano de fundo transparente, medir 24 x 24 dp e estar no formato de um
VectorDrawable.
Crie um ícone que indique visualmente a finalidade do bloco. Isso ajuda os usuários a identificar se o bloco atende às necessidades deles. Por exemplo, você pode criar um ícone de cronômetro para um bloco de um app de fitness que permite que os usuários iniciem uma sessão de treino.
Criar e declarar o TileService
Crie um serviço para o bloco que estenda a classe TileService.
class MyQSTileService : TileService() { // Called when the user adds your tile. override fun onTileAdded() { super.onTileAdded() } // Called when your app can update your tile. override fun onStartListening() { super.onStartListening() } // Called when your app can no longer update your tile. override fun onStopListening() { super.onStopListening() } // Called when the user taps on your tile in an active or inactive state. override fun onClick() { super.onClick() } // Called when the user removes your tile. override fun onTileRemoved() { super.onTileRemoved() } }
Declare o TileService no arquivo de manifesto do app. Adicione o nome e o rótulo
do seu TileService (até 18 caracteres para android:label), o ícone personalizado
que você criou na seção anterior e a permissão adequada.
<!-- 18-character limit for android:label. -->
<service
android:name=".MyQSTileService"
android:exported="true"
android:label="@string/my_default_tile_label"
android:icon="@drawable/my_default_icon_label"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
Gerenciar o TileService
Depois de criar e declarar o TileService no manifesto do app, você
precisa gerenciar o estado dele.
TileService é um serviço vinculado. O TileService é vinculado quando
solicitado pelo app ou se o sistema precisa se comunicar com ele. Um ciclo de vida de serviço vinculado típico contém os quatro métodos de callback a seguir: onCreate(), onBind(), onUnbind() e onDestroy(). Esses métodos são invocados pelo sistema sempre que o
serviço entra em uma nova fase do ciclo de vida.
Visão geral do ciclo de vida do TileService
Além dos callbacks que controlam o ciclo de vida do serviço vinculado, é necessário
implementar outros métodos específicos do ciclo de vida de TileService. Esses métodos
podem ser chamados fora de onCreate() e onDestroy() porque os métodos de ciclo de vida
Service e TileService são chamados em duas
linhas de execução assíncronas separadas.
O ciclo de vida da TileService contém os seguintes métodos, que são invocados
pelo sistema sempre que a TileService entra em uma nova fase do ciclo de vida:
onTileAdded(): esse método é chamado apenas quando o usuário adiciona o bloco pela primeira vez e se ele remover e adicionar o bloco novamente. Esse é o melhor momento para fazer qualquer inicialização única. No entanto, isso pode não atender a todas as inicializações necessárias.onStartListening()eonStopListening(): esses métodos são chamados sempre que a atualização do app atualiza o bloco, o que acontece com frequência. OTileServicepermanece vinculado entreonStartListening()eonStopListening(), permitindo que o app modifique o bloco e envie atualizações.onTileRemoved(): esse método é chamado apenas se o usuário remover o bloco.
Selecione um modo de audição
O TileService escuta no modo ativo ou não ativo. Recomendamos
o uso do modo ativo, que precisa ser declarado no manifesto do app.
Caso contrário,
o TileService é o modo padrão e não precisa ser declarado.
Não presuma que o TileService vai existir fora do par de métodos onStartListening() e
onStopListening().
Modo ativo (recomendado)
Use o modo ativo para um TileService que detecta e monitora o próprio estado no
próprio processo. Um TileService no modo ativo é vinculado a onTileAdded(),
onTileRemoved(), eventos de toque e quando solicitado pelo processo do app.
Recomendamos o modo ativo se o TileService for notificado quando o estado do bloco
precisar ser atualizado pelo próprio processo. Os blocos ativos limitam a sobrecarga no
sistema porque não precisam ser vinculados sempre que o painel de Configurações rápidas
fica visível para o usuário.
O método estático TileService.requestListeningState() pode ser chamado para
solicitar o início do estado de detecção e receber um callback para
onStartListening().
Para declarar o modo ativo, adicione META_DATA_ACTIVE_TILE ao
arquivo de manifesto do app.
<service ...>
<meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
android:value="true" />
...
</service>
Modo inativo
O modo não ativo é o padrão. Um TileService estará no modo inativo se
estiver vinculado sempre que o bloco estiver visível para o usuário. Isso significa que o
TileService pode ser criado e vinculado novamente em momentos fora do controle dele. Ele
também pode ser desvinculado e destruído quando o usuário não estiver visualizando o bloco.
O app recebe um callback para onStartListening() depois que o usuário abre o
painel de Configurações rápidas. É possível atualizar o objeto Tile quantas vezes quiser entre onStartListening() e onStopListening().
Não é necessário declarar o modo não ativo: não adicione o
META_DATA_ACTIVE_TILE ao arquivo de manifesto do app.
Visão geral dos estados de blocos
Depois que um usuário adiciona seu bloco, ele sempre existe em um dos estados a seguir.
STATE_ACTIVE: indica um estado ativado. O usuário pode interagir com o bloco enquanto ele estiver nesse estado.Por exemplo, em um bloco de app de fitness que permite que os usuários iniciem uma sessão de treino cronometrada,
STATE_ACTIVEsignifica que o usuário iniciou uma sessão de treino e o timer está em execução.STATE_INACTIVE: indica um estado desativado ou pausado. O usuário pode interagir com o bloco enquanto ele estiver nesse estado.Para usar o exemplo do bloco do app de fitness novamente, um bloco em
STATE_INACTIVEsignifica que o usuário não iniciou uma sessão de treino, mas pode fazer isso se quiser.STATE_UNAVAILABLE: indica um estado temporariamente indisponível. O usuário não pode interagir com o bloco enquanto ele estiver nesse estado.Por exemplo, um bloco em
STATE_UNAVAILABLEsignifica que ele não está disponível para o usuário no momento por algum motivo.
O sistema define apenas o estado inicial do objeto Tile. Você define o estado do objeto Tile
durante o restante do ciclo de vida dele.
O sistema pode colorir o ícone e o plano de fundo do bloco para refletir o estado do objeto
Tile. Os objetos Tile definidos como STATE_ACTIVE são os mais escuros, com
STATE_INACTIVE e STATE_UNAVAILABLE cada vez mais claros. A tonalidade exata
é específica do fabricante e da versão.
Atualizar o bloco
Você pode atualizar o bloco quando receber um callback para onStartListening().
Dependendo do modo do bloco, ele pode ser atualizado pelo menos uma vez até
receber um callback para onStopListening().
No modo ativo, é possível atualizar o bloco exatamente uma vez antes de receber um
callback para onStopListening(). No modo não ativo, é possível atualizar o bloco quantas
vezes quiser entre onStartListening() e onStopListening().
Para recuperar o objeto Tile, chame getQsTile(). Para atualizar
campos específicos do objeto Tile, chame os seguintes métodos:
Chame updateTile() para atualizar o bloco depois de definir os campos do objeto Tile com os valores corretos. Isso fará com que o sistema
analise os dados atualizados do bloco e atualize a interface.
data class StateModel(val enabled: Boolean, val label: String, val icon: Icon) override fun onStartListening() { super.onStartListening() val state = getStateFromService() qsTile.label = state.label qsTile.contentDescription = state.label qsTile.state = if (state.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.icon = state.icon qsTile.updateTile() }
Processar toques
Os usuários podem tocar no bloco para acionar uma ação se ele estiver em
STATE_ACTIVE ou STATE_INACTIVE. Em seguida, o sistema invoca o callback
onClick() do app.
Depois que o app recebe um callback para onClick(), ele pode iniciar uma caixa de diálogo ou
atividade, acionar um trabalho em segundo plano ou mudar o estado do bloco.
var counter = 0 override fun onClick() { super.onClick() counter++ qsTile.state = if (counter % 2 == 0) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.label = "Clicked $counter times" qsTile.contentDescription = qsTile.label qsTile.updateTile() }
Abrir uma caixa de diálogo
showDialog() fecha o painel de Configurações rápidas e mostra uma caixa de diálogo.
Use uma caixa de diálogo para adicionar contexto à ação se ela exigir mais informações
ou o consentimento do usuário.
Iniciar uma atividade
startActivityAndCollapse() inicia uma atividade enquanto recolhe o
painel. As atividades são úteis se houver informações mais detalhadas para mostrar
do que em uma caixa de diálogo ou se a ação for altamente interativa.
Se o app exigir uma interação significativa do usuário, ele só deverá iniciar uma atividade como último recurso. Em vez disso, use uma caixa de diálogo ou uma alternância.
Tocar e pressionar um bloco abre a tela Informações do app para o usuário. Para modificar
esse comportamento e iniciar uma atividade para definir preferências, adicione um
<intent-filter> a uma das suas atividades com
ACTION_QS_TILE_PREFERENCES.
A partir da API 28 do Android, o PendingIntent precisa
ter o Intent.FLAG_ACTIVITY_NEW_TASK:
if (Build.VERSION.SDK_INT >= 28) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
Como alternativa, é possível adicionar a flag no AndroidManifest.xml na seção Activity específica.
Marcar o bloco como alternável
Recomendamos marcar o bloco como alternável se ele funcionar principalmente como uma chave de dois estados, que é o comportamento mais comum dos blocos. Isso ajuda a fornecer informações sobre o comportamento do bloco ao sistema operacional e melhorar a acessibilidade geral.
Defina os metadados TOGGLEABLE_TILE como true para marcar o bloco como alternável.
<service ...>
<meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
android:value="true" />
</service>
Realizar apenas ações seguras em dispositivos bloqueados com segurança
O bloco pode ser exibido sobre a tela de bloqueio em dispositivos bloqueados. Se o bloco
contiver informações sensíveis, verifique o valor de isSecure() para
determinar se o dispositivo está em um estado seguro, e o TileService precisa
mudar o comportamento de acordo.
Se a ação do bloco for segura para ser realizada enquanto o dispositivo estiver bloqueado, use startActivity()
para iniciar uma atividade sobre a tela de bloqueio.
Se a ação do bloco não for segura, use unlockAndRun() para solicitar que o usuário
desbloqueie o dispositivo. Se for bem-sucedido, o sistema vai executar o objeto Runnable que você transmitir para esse método.
Categorizar o bloco
Para melhorar a experiência do usuário nas Configurações rápidas, você pode categorizar seu bloco. O sistema organiza os blocos em categorias como Conectividade, Tela e Privacidade. O sistema usa essas categorias para classificar e agrupar blocos no modo de edição das Configurações rápidas, o que facilita a localização e o gerenciamento pelos usuários.
Implementação
Para especificar uma categoria para o TileService, adicione um campo de metadados à
declaração de serviço no arquivo AndroidManifest.xml:
- No
AndroidManifest.xml, dentro do elemento<service>doTileService, adicione um elemento<meta-data>. android:name: defina esse valor comoandroid.service.quicksettings.TILE_CATEGORY.android:value: atribua uma das constantes de categoria predefinidas, comoandroid.service.quicksettings.CATEGORY_CONNECTIVITYouandroid.service.quicksettings.CATEGORY_DISPLAY.
Como mostrado no exemplo a seguir:
<service
android:name=".MyConnectivityTileService"
[...]
>
<meta-data android:name="android.service.quicksettings.TILE_CATEGORY"
android:value="android.service.quicksettings.CATEGORY_CONNECTIVITY" />
</service>
A API oferece um conjunto de categorias predefinidas para você escolher. Essas categorias
são definidas como constantes de string na classe TileService.
Se uma categoria não for especificada, o sistema vai atribuir automaticamente uma categoria padrão:
- De apps do sistema: para blocos que fazem parte de um aplicativo do sistema.
- De apps que você instalou: para blocos de aplicativos instalados pelo usuário.
Embora os dispositivos Google Pixel usem categorias nas Configurações rápidas, os OEMs podem usar ou ignorar essas informações de categoria nas respectivas IUs do sistema.
Pedir para o usuário adicionar Sua vez
Para adicionar o bloco manualmente, os usuários precisam seguir várias etapas:
- Deslize para baixo para abrir o painel "Configurações rápidas".
- Toque no botão de edição.
- Role todos os blocos no dispositivo até encontrar o seu.
- Toque e pressione o bloco e arraste-o para a lista de blocos ativos.
O usuário também pode mover ou remover o bloco a qualquer momento.
No Android 13, você pode usar o método requestAddTileService()
para facilitar a adição do bloco a um dispositivo. Esse método
solicita que os usuários adicionem rapidamente o bloco diretamente ao painel de
Configurações rápidas. O comando inclui o nome do aplicativo, o rótulo fornecido
e o ícone.
public void requestAddTileService (
ComponentName tileServiceComponentName,
CharSequence tileLabel,
Icon icon,
Executor resultExecutor,
Consumer<Integer> resultCallback
)
O callback contém informações sobre se o bloco foi adicionado, não adicionado, se já estava lá ou se ocorreu algum erro.
Use seu bom senso ao decidir quando e com que frequência solicitar aos usuários. Recomendamos
chamar requestAddTileService() apenas no contexto, como
quando o usuário interage pela primeira vez com um recurso que o bloco facilita.
O sistema pode optar por interromper o processamento de solicitações de um determinado
ComponentName se ele tiver sido negado pelo usuário um número suficiente de vezes. O
usuário é determinado pelo Context usado para recuperar esse
serviço: ele precisa corresponder ao usuário atual.