As "Configurações rápidas" são blocos exibidos no painel "Configurações rápidas".
que representam ações, que os usuários podem tocar para concluir rapidamente tarefas recorrentes.
Seu app pode fornecer um bloco personalizado para os usuários usando a TileService
.
e use um objeto Tile
para rastrear o estado do bloco. Por exemplo:
você pode criar um bloco que permita aos usuários ativar uma VPN fornecida pelo seu app ou
![Painel "Configurações rápidas" com o bloco "VPN" ativado
ligado e desligado](https://developer.android.google.cn/static/develop/ui/views/images/quick-settings-vpn-on-off.png?authuser=19&hl=pt-br)
Decidir quando criar um bloco
Recomendamos a criação de blocos para funcionalidades específicas esperadas dos usuários com frequência ou que precisem de acesso rápido (ou ambos). O método mais eficaz os blocos são os que correspondem a essas duas qualidades, fornecendo acesso rápido a ações realizadas com frequência.
Por exemplo, você pode criar um bloco para um aplicativo de condicionamento físico 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 permitiria aos usuários rever todo o histórico de treino.
![Casos de uso do bloco do app fitness](https://developer.android.google.cn/static/develop/ui/views/images/use-cases-fitness-tiles.png?authuser=19&hl=pt-br)
Para ajudar a melhorar a facilidade de descoberta e a facilidade de uso do seu bloco, recomendamos evitando certas práticas:
Evite usar blocos para iniciar um app. Use um atalho de app ou um padrão acesso rápido.
Evite usar blocos para ações únicas do usuário. Use um atalho de app ou notification.
Evite criar muitos blocos. Recomendamos no máximo duas por app. Use um atalho do app.
Evite usar blocos que exibem informações, mas não são interativos para usuários. Em vez disso, use uma notificação ou um widget.
Criar seu bloco
Para criar um bloco, é necessário primeiro criar um ícone de bloco apropriado, depois
criar e declarar o TileService
no arquivo de manifesto do app.
O exemplo de Configurações rápidas fornece um exemplo de como criar e gerenciar um bloco.
Crie seu ícone personalizado
Você precisará fornecer um ícone personalizado, que será exibido no bloco na guia
Configurações. Você vai adicionar esse ícone ao declarar o TileService
,
descritos na próxima seção. O ícone deve ser branco sólido com
fundo transparente, medir 24 x 24 dp, na forma de
VectorDrawable
![Exemplo de um drawable vetorial](https://developer.android.google.cn/static/develop/ui/views/images/vector-drawable.png?authuser=19&hl=pt-br)
Crie um ícone que indique visualmente a finalidade do bloco. Isso ajuda os usuários identificar facilmente se o bloco atende às necessidades dela. Por exemplo, é possível criar um ícone de um cronômetro em um bloco de um app fitness que permite aos usuários iniciar uma sessão de treino.
Criar e declarar o TileService
Crie um serviço para o bloco que estenda a classe TileService
.
Kotlin
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() } }
Java
public class MyQSTileService extends TileService { // Called when the user adds your tile. @Override public void onTileAdded() { super.onTileAdded(); } // Called when your app can update your tile. @Override public void onStartListening() { super.onStartListening(); } // Called when your app can no longer update your tile. @Override public void onStopListening() { super.onStopListening(); } // Called when the user taps on your tile in an active or inactive state. @Override public void onClick() { super.onClick(); } // Called when the user removes your tile. @Override public void onTileRemoved() { super.onTileRemoved(); } }
Declare o TileService
no arquivo de manifesto do app. Adicionar o nome e o rótulo
do TileService
, o ícone personalizado que você criou na seção anterior;
e a permissão adequada.
<service
android:name=".MyQSTileService"
android:exported="true"
android:label="@string/my_default_tile_label" // 18-character limit.
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 seu TileService
Depois de criar e declarar o TileService
no manifesto do app, você pode
para gerenciar o estado.
TileService
é um serviço vinculado. Seu TileService
será vinculado quando
solicitado pelo app ou se o sistema precisa se comunicar com ele. Uma configuração típica
bound-service lifecycle contém os quatro métodos de callback a seguir:
onCreate()
, onBind()
, onUnbind()
e
onDestroy()
. Esses métodos são invocados pelo sistema cada vez 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, é preciso
implementar outros métodos específicos para o ciclo de vida da TileService
. Esses métodos
pode ser chamado fora de onCreate()
e onDestroy()
porque Service
métodos do ciclo de vida e os métodos 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 o TileService
entrar em uma nova fase do ciclo de vida:
onTileAdded()
: esse método é chamado somente quando o usuário adiciona seu pela primeira vez e se o usuário remover e adicionar seu bloco novamente. Esse é o melhor momento para fazer qualquer inicialização única. No entanto, isso pode que não atendam a toda a inicialização necessária.onStartListening()
eonStopListening()
: esses métodos são chamados sempre que o app atualiza o bloco e são chamados com frequência. ATileService
permanece vinculado entreonStartListening()
eonStopListening()
, permitindo que o app modifique o bloco e envie atualizações.onTileRemoved()
: esse método só será chamado se o usuário remover suas bloco.
Selecione um modo de escuta
Seu TileService
detecta no modo ativo ou não ativo. Recomendamos
usando o 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 suponha que seu TileService
ficará fora de onStartListening()
e
onStopListening()
de métodos.
Modo ativo (recomendado)
Usar o modo ativo para um TileService
que detecta e monitora o estado na
processo próprio. Um TileService
no modo ativo está 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
deve ser atualizada por um processo próprio. Os blocos ativos limitam o esforço
sistema, porque eles não precisam ser vinculados sempre que o painel "Configurações rápidas"
se torna 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 não ativo
O modo não ativo é o modo padrão. Uma TileService
ficará no modo inativo se
ele é vinculado sempre que o bloco está visível para o usuário. Isso significa que seus
TileService
pode ser criado e vinculado novamente às vezes além do controle dele. Ela
também pode ser desvinculado e destruído quando o usuário não estiver visualizando o bloco.
O app recebe uma chamada de retorno para onStartListening()
depois que o usuário abre a
Configurações rápidas. É possível atualizar o objeto Tile
quantas vezes você quiser
entre onStartListening()
e onStopListening()
.
Não é necessário declarar o modo não ativo. Basta não adicionar o
META_DATA_ACTIVE_TILE
ao arquivo de manifesto do app.
Visão geral dos estados de bloco
Depois que um usuário adiciona seu bloco, ele sempre existe em um dos seguintes estados.
STATE_ACTIVE
: indica o estado ativado ou ativado. O usuário pode interagem com o bloco nesse estado.Por exemplo, para um bloco de app fitness que permite aos usuários iniciar um treino cronometrado. sessão,
STATE_ACTIVE
significa que o usuário iniciou um treino. e o cronômetro está em execução.STATE_INACTIVE
: indica um estado desativado ou pausado. O usuário pode interagem com o bloco nesse estado.Para usar o exemplo do bloco do app fitness novamente, um bloco em
STATE_INACTIVE
precisaria significa que o usuário não iniciou uma sessão de treino, mas pode fazê-lo se queriam.STATE_UNAVAILABLE
: indica um estado temporariamente indisponível. A o usuário não pode interagir com o bloco enquanto estiver nesse estado.Por exemplo, um bloco em
STATE_UNAVAILABLE
significa que o bloco não é disponível para o usuário por algum motivo.
O sistema define apenas o estado inicial do objeto Tile
. Você definiu o Tile
do objeto ao longo do restante do ciclo de vida.
O sistema pode colorir o ícone do bloco e o plano de fundo para refletir o estado do seu
Tile
. Objetos Tile
definidos como STATE_ACTIVE
são os mais escuros, com
O STATE_INACTIVE
e o STATE_UNAVAILABLE
estão cada vez mais leves. A tonalidade exata
é específico para o fabricante e a versão.
![Bloco de VPN colorido para refletir os estados dos objetos](https://developer.android.google.cn/static/develop/ui/views/images/state-hues.png?authuser=19&hl=pt-br)
Atualizar seu bloco
É possível atualizar o Bloco assim que você receber um callback para onStartListening()
.
Dependendo do modo do bloco, ele pode ser atualizado pelo menos uma vez até
recebendo um callback para onStopListening()
.
No modo ativo, é possível atualizar seu bloco exatamente uma vez antes de receber
para onStopListening()
. No modo inativo, é possível atualizar seu bloco como
quantas vezes você 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:
Você precisa chamar updateTile()
para atualizar o bloco quando terminar de definir o
campos do objeto Tile
nos valores corretos. Isso fará com que o sistema
analisar os dados de bloco atualizados e atualizar a interface.
Kotlin
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 = tile.label qsTile.state = if (state.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.icon = state.icon qsTile.updateTile() }
Java
public class StateModel { final boolean enabled; final String label; final Icon icon; public StateModel(boolean e, String l, Icon i) { enabled = e; label = l; icon = i; } } @Override public void onStartListening() { super.onStartListening(); StateModel state = getStateFromService(); Tile tile = getQsTile(); tile.setLabel(state.label); tile.setContentDescription(state.label); tile.setState(state.enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); tile.setIcon(state.icon); tile.updateTile(); }
Processar toques
Os usuários podem tocar no bloco para iniciar uma ação se ele estiver
STATE_ACTIVE
ou STATE_INACTIVE
. Em seguida, o sistema invoca
Callback onClick()
.
Quando o app receber um callback para onClick()
, ele poderá iniciar uma caixa de diálogo ou
acionar o trabalho em segundo plano ou mudar o estado do bloco.
Kotlin
var clicks = 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() }
Java
int clicks = 0; @Override public void onClick() { super.onClick(); counter++; Tile tile = getQsTile(); tile.setState((counter % 2 == 0) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); tile.setLabel("Clicked " + counter + " times"); tile.setContentDescription(tile.getLabel()); tile.updateTile(); }
Abrir uma caixa de diálogo
O showDialog()
fecha o painel "Configurações rápidas" e mostra uma caixa de diálogo.
Use uma caixa de diálogo para contextualizar a ação se ela precisar de mais entradas
ou o consentimento do usuário.
Iniciar uma atividade
startActivityAndCollapse()
inicia uma atividade ao recolher o
do painel de controle. As atividades são úteis quando há informações mais detalhadas para exibir
do que em uma caixa de diálogo ou
caso sua ação seja muito interativa.
Se seu aplicativo exigir uma interação significativa do usuário, ele deverá iniciar uma atividades apenas como último recurso. Em vez disso, use uma caixa de diálogo ou um botão de ativação.
Quando o usuário toca e mantém pressionado um bloco, a tela Informações do app é exibida. Para substituir
esse comportamento e iniciar uma atividade para definir preferências, adicione um
<intent-filter>
em uma das suas atividades com
ACTION_QS_TILE_PREFERENCES
.
A partir do nível 28 da API do Android, a PendingIntent
precisa
têm o Intent.FLAG_ACTIVITY_NEW_TASK
:
if (Build.VERSION.SDK_INT >= 28) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
Como alternativa, adicione a flag no AndroidManifest.xml
no
Activity
.
Marcar seu bloco como alternável
Recomendamos marcar seu bloco como alternável se ele funcionar principalmente como um interruptor de dois estados (que é o comportamento mais comum dos blocos). Isso ajuda fornecem informações sobre o comportamento do bloco para o sistema operacional e 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>
Executar apenas ações seguras em dispositivos bloqueados com segurança
Seu bloco pode aparecer na parte de cima da tela de bloqueio em dispositivos bloqueados. Se o bloco
contiver informações confidenciais, verifique o valor de isSecure()
para
determina se o dispositivo está em um estado seguro e se o TileService
precisa
para mudar o comportamento de acordo.
Se for seguro realizar a ação de bloco enquanto o dispositivo estiver bloqueado, use startActivity()
para iniciar uma atividade na parte superior da tela de bloqueio.
Se a ação do bloco não for segura, use unlockAndRun()
para pedir que o usuário
desbloquear o dispositivo. Se bem-sucedido, o sistema executa o
objeto Runnable
que você transmite a esse
.
Pedir que o usuário adicione seu bloco
Para adicionar seu 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.
- Percorra todos os blocos no dispositivo até localizar o bloco.
- Mantenha seu bloco pressionado e arraste-o para a lista de blocos ativos.
O usuário também pode mover ou remover seu bloco a qualquer momento.
No Android 13 e versões mais recentes, você pode usar o método requestAddTileService()
.
para que seja muito mais fácil para os usuários adicionarem seu bloco a um dispositivo. Esse método
solicita que os usuários adicionem rapidamente seu bloco diretamente ao Quick
Configurações. O comando inclui o nome do aplicativo, o rótulo fornecido
e um ícone.
![Solicitação da API Quick Settings Placement](https://developer.android.google.cn/static/develop/ui/views/images/placement-api-user-prompt.png?authuser=19&hl=pt-br)
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 ou não. adicionado, se já estava lá ou se ocorreu algum erro.
Tenha cautela ao decidir quando e com que frequência enviar solicitações aos usuários. Qa
recomendamos chamar requestAddTileService()
somente no contexto, como
quando o usuário interage pela primeira vez com um recurso facilitado pelo seu bloco.
O sistema pode optar por interromper o processamento de solicitações para um determinado
ComponentName
se tiver sido negada pelo usuário muitas vezes antes. A
o usuário é determinado pelo Context
usado para recuperar isso.
serviço, ou seja, ele precisa corresponder ao usuário atual.