Cómo crear tarjetas de Configuración rápida personalizadas para tu app

La Configuración rápida son tarjetas que se muestran en el panel de Configuración rápida. que representan acciones, que los usuarios pueden presionar para completar tareas recurrentes con rapidez. Tu app puede proporcionar una tarjeta personalizada a los usuarios a través de TileService y usa un objeto Tile para hacer un seguimiento del estado de la tarjeta. Por ejemplo: Podrías crear una tarjeta que permita a los usuarios activar o desactivar una VPN desactivado.

Panel de Configuración rápida con la tarjeta de VPN activada
  encender y apagar
Figura 1: Panel de Configuración rápida con la tarjeta de VPN activada encenderse y apagarse.

Cómo decidir cuándo crear una tarjeta

Recomendamos crear tarjetas para funciones específicas que esperas que los usuarios acceder con frecuencia o necesitar un acceso rápido (o ambos). La solución más eficaz las tarjetas son las que coinciden con ambas cualidades, lo que proporciona acceso rápido a las acciones realizadas con frecuencia.

Por ejemplo, puedes crear una tarjeta para una app de fitness que permita a los usuarios iniciar rápidamente una sesión de entrenamiento. Sin embargo, no te recomendamos crear una tarjeta para la misma app que permitiría a los usuarios revisar todo su historial de entrenamiento.

Casos de uso de la tarjeta de apps de fitness
Figura 2: Ejemplos de tarjetas recomendadas y no recomendadas para una app de fitness

Para ayudar a mejorar la visibilidad y facilidad de uso de tu tarjeta, te recomendamos y evitar ciertas prácticas:

  • Evita usar tarjetas para iniciar una app. Usa un acceso directo a una aplicación o un estándar selector.

  • Evita usar tarjetas para las acciones del usuario únicas. Usa un acceso directo a una app o notification.

  • Evita crear demasiadas tarjetas. Recomendamos un máximo de dos por app. Usa un atajo a la app.

  • Evita usar mosaicos que muestren información, pero que no sean interactivos para usuarios. En su lugar, usa una notificación o un widget.

Cómo crear tu tarjeta

Para crear una tarjeta, primero debes crear un ícono de tarjeta adecuado y, luego, Crea y declara tu TileService en el archivo de manifiesto de tu app.

El ejemplo de Configuración rápida proporciona un ejemplo de cómo crear y administrar una tarjeta.

Crea tu ícono personalizado

Deberás proporcionar un icono personalizado, que aparecerá en el mosaico en el menú desplegable Panel de configuración (Agregarás este ícono cuando declares el TileService, que se describe en la siguiente sección). El ícono debe ser de color blanco sólido con una fondo transparente, medir 24 x 24 dp y tener la forma de VectorDrawable

Ejemplo de un elemento de diseño vectorial
Figura 3: Ejemplo de un elemento de diseño vectorial.

Crea un ícono que sugiera visualmente el propósito de tu tarjeta. Esto ayuda a los usuarios identificar fácilmente si tu mosaico se ajusta a sus necesidades. Por ejemplo, podrías crear una ícono de un cronómetro para una tarjeta de una aplicación de fitness que permite a los usuarios iniciar una sesión de entrenamiento físico.

Cómo crear y declarar tu TileService

Crea un servicio para tu tarjeta que extienda la clase 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();
  }
}

Declara tu TileService en el archivo de manifiesto de tu app. Agrega el nombre y la etiqueta de tu TileService, el ícono personalizado que creaste en la sección anterior, y el permiso correspondiente.

 <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>

Cómo administrar tu TileService

Una vez que hayas creado y declarado tu TileService en el manifiesto de la app, podrás la administración de su estado.

TileService es un servicio vinculado. Tu TileService está vinculado cuando solicitada por tu app o si el sistema necesita comunicarse con ella. Un bound-service lifecycle contiene los siguientes cuatro métodos de devolución de llamada: onCreate(), onBind(), onUnbind() y onDestroy(). El sistema invoca estos métodos cada vez que servicio entra en una nueva fase del ciclo de vida.

Descripción general del ciclo de vida de TileService

Además de las devoluciones de llamada que controlan el ciclo de vida del servicio vinculado, debes implementar otros métodos específicos para el ciclo de vida de TileService Estos métodos se puede llamar fuera de onCreate() y onDestroy() porque el Service a los métodos de ciclo de vida y a los métodos de ciclo de vida de TileService se llama en dos subprocesos asíncronos separados.

El ciclo de vida de TileService contiene los siguientes métodos, que se invocan que el sistema hace cada vez que tu TileService ingresa en una nueva fase del ciclo de vida:

  • onTileAdded(): Se llama a este método solo cuando el usuario agrega tu a la tarjeta por primera vez y si el usuario la quita y vuelve a agregar. Este es el mejor momento para realizar cualquier inicialización única. Sin embargo, esto puede no satisface toda la inicialización necesaria.

  • onStartListening() y onStopListening(): Estos métodos son a los que se llama cada vez que la app actualiza la tarjeta, y se los llama con frecuencia. El TileService permanece limitada entre onStartListening() y onStopListening(), lo que permite que tu app modifique la tarjeta y envíe actualizaciones.

  • onTileRemoved(): Se llama a este método solo si el usuario quita la mosaico.

Selecciona un modo de escucha

Tu TileService escucha en modo activo o no activo. Recomendaciones con el modo activo, que deberás declarar en el manifiesto de la app. De lo contrario, TileService es el modo estándar y no es necesario declararlo.

No asumas que tu TileService permanecerá fuera de onStartListening() y par de métodos onStopListening().

Usa el modo activo para un TileService que escucha y supervisa su estado en el propio proceso. Una TileService en el modo activo está vinculada a onTileAdded(), onTileRemoved(), presiona eventos y cuando lo solicite el proceso de la app.

Recomendamos el modo activo si tu TileService recibe una notificación cuando se muestra el estado de la tarjeta debe actualizarse mediante su propio proceso. Los mosaicos activos limitan la sobrecarga de ya que no es necesario vincularlos cada vez que el panel se hace visible para el usuario.

Se puede llamar al método TileService.requestListeningState() estático para solicitar el inicio del estado de escucha y recibir una devolución de llamada para onStartListening()

Para declarar el modo activo, agrega META_DATA_ACTIVE_TILE a tu archivo de manifiesto de tu app.

<service ...>
    <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
         android:value="true" />
    ...
</service>

Modo inactivo

El modo no activo es el modo estándar. Un TileService está en modo no activo si se vincula cada vez que tu tarjeta es visible para el usuario. Esto significa que tu Es posible que TileService se vuelva a crear y vincular en ocasiones fuera de su control. Integra también se puede desvincular y destruir cuando el usuario no esté viendo la tarjeta.

Tu app recibe una devolución de llamada a onStartListening() después de que el usuario abre su Panel de Configuración rápida Puedes actualizar tu objeto Tile todas las veces que entre onStartListening() y onStopListening().

No es necesario declarar el modo no activo; simplemente, no agregues el META_DATA_ACTIVE_TILE en el archivo de manifiesto de tu app.

Descripción general de los estados de los mosaicos

Después de que un usuario agrega tu tarjeta, siempre existe en uno de los siguientes estados.

  • STATE_ACTIVE: Indica un estado activado o habilitado. El usuario puede interactuar con tu tarjeta mientras esté en este estado.

    Por ejemplo, para una tarjeta de app de fitness que permite a los usuarios iniciar un entrenamiento cronometrado STATE_ACTIVE indicaría que el usuario inició un entrenamiento. sesión y el temporizador está en funcionamiento.

  • STATE_INACTIVE: Indica un estado apagado o pausado. El usuario puede interactuar con tu tarjeta mientras esté en este estado.

    Para volver a usar el ejemplo de la tarjeta de la app de fitness, se necesitaría una tarjeta de STATE_INACTIVE significa que el usuario no ha iniciado una sesión de entrenamiento, pero podría hacerlo si que querían.

  • STATE_UNAVAILABLE: Indica un estado que no se encuentra disponible temporalmente. El el usuario no puede interactuar con tu mosaico en este estado.

    Por ejemplo, una tarjeta en STATE_UNAVAILABLE significa que no se disponibles actualmente para el usuario por algún motivo.

El sistema solo establece el estado inicial del objeto Tile. Estableces el Tile del objeto durante el resto de su ciclo de vida.

El sistema puede cambiar el tono del ícono y el fondo del mosaico para reflejar el estado de tu Tile. Los objetos Tile establecidos en STATE_ACTIVE son los más oscuros, con STATE_INACTIVE y STATE_UNAVAILABLE son cada vez más claros. El matiz exacto es específica del fabricante y la versión.

Se cambió el tono del mosaico de VPN para reflejar los estados de los objetos
Figura 4: Ejemplos de un tono de mosaico que refleja el estado de la tarjeta (estados activo, inactivo y no disponible, respectivamente).

Cómo actualizar tu mosaico

Podrás actualizar tu tarjeta una vez que recibas una devolución de llamada a onStartListening(). Según el modo de la tarjeta, esta se puede actualizar al menos una vez hasta recibiendo una devolución de llamada a onStopListening().

En el modo activo, puedes actualizar tu tarjeta exactamente una vez antes de recibir un devolución de llamada a onStopListening(). En el modo no activo, puedes actualizar tu tarjeta como todas las veces que quieras entre onStartListening() y onStopListening().

Para recuperar tu objeto Tile, llama a getQsTile(). Para actualizar campos específicos de tu objeto Tile, llama a los siguientes métodos:

Debes llamar a updateTile() para actualizar la tarjeta una vez que termines de configurar la del objeto Tile con los valores correctos. Esto hará que el sistema analizar los datos de tarjetas actualizados y actualizar la IU.

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();
}

Cómo controlar los toques

Los usuarios pueden presionar tu tarjeta para activar una acción si esta está en STATE_ACTIVE o STATE_INACTIVE. Luego, el sistema invoca la interfaz Devolución de llamada onClick().

Una vez que tu app reciba una devolución de llamada a onClick(), podrá iniciar un diálogo o actividad, activar trabajos en segundo plano o cambiar el estado de la tarjeta.

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();
}

Iniciar un diálogo

showDialog() contrae el panel de Configuración rápida y muestra un diálogo. Usa un diálogo para agregar contexto a tu acción si se requiere una entrada adicional o el consentimiento del usuario.

Cómo iniciar una actividad

startActivityAndCollapse() inicia una actividad mientras se contrae la panel. Las actividades son útiles si hay información más detallada para mostrar. que en un diálogo o si tu acción es muy interactiva.

Si tu app requiere una interacción significativa del usuario, esta debe iniciar un la actividad solo como último recurso. En su lugar, considera usar un diálogo o un botón de activación.

Si el usuario mantiene presionada una tarjeta, aparece la pantalla App Info. Para anular este comportamiento y, en su lugar, inicia una actividad para configurar preferencias, agrega una <intent-filter> a una de tus actividades con ACTION_QS_TILE_PREFERENCES

A partir de la API 28 de Android, el elemento PendingIntent debe tienen el Intent.FLAG_ACTIVITY_NEW_TASK:

if (Build.VERSION.SDK_INT >= 28) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

De forma alternativa, puedes agregar la marca en el AndroidManifest.xml en la ruta Sección Activity.

Marca tu tarjeta como seleccionable

Te recomendamos que marques la tarjeta para que se pueda activar o desactivar si funciona principalmente como una interruptor de dos estados (que es el comportamiento más común de las tarjetas). Esto ayuda proporcionar información sobre el comportamiento de la tarjeta al sistema operativo y mejorar la accesibilidad general.

Establece los metadatos de TOGGLEABLE_TILE en true para marcar tu tarjeta como se puede activar o desactivar.

<service ...>
  <meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
    android:value="true" />
</service>

Realiza solo acciones seguras en dispositivos bloqueados de forma segura

Tu mosaico puede aparecer en la parte superior de la pantalla de bloqueo en dispositivos bloqueados. Si la tarjeta contiene información sensible, verifica el valor de isSecure() para determinar si el dispositivo está en estado seguro, y tu TileService debería cambiar su comportamiento en consecuencia.

Si es seguro realizar la acción de la tarjeta con el dispositivo bloqueado, usa startActivity(). para iniciar una actividad sobre la pantalla de bloqueo.

Si la acción de la tarjeta no es segura, usa unlockAndRun() para solicitarle al usuario que haga lo siguiente: desbloquear su dispositivo. Si tiene éxito, el sistema ejecuta Runnable que pasas a esta .

Cómo pedirle al usuario que agregue tu tarjeta

Para agregar tu tarjeta de forma manual, los usuarios deben seguir varios pasos:

  1. Desliza el dedo hacia abajo para abrir el panel de Configuración rápida.
  2. Presiona el botón Editar.
  3. Desplázate por todas las tarjetas de su dispositivo hasta que encuentren la tuya.
  4. Mantén presionada la tarjeta y arrástrala a la lista de tarjetas activas.

El usuario también puede mover o quitar tu tarjeta en cualquier momento.

A partir de Android 13, puedes usar el método requestAddTileService() para que a los usuarios les resulte mucho más fácil agregar tu tarjeta a un dispositivo. Este método muestra a los usuarios una solicitud para agregar rápidamente tu tarjeta directamente a su cuenta de Quick Panel de configuración La instrucción incluye el nombre de la aplicación, la etiqueta proporcionada e ícono.

Mensaje de la API de posición de configuración rápida
Figura 5: Mensaje de la API de Quick Settings Position
public void requestAddTileService (
  ComponentName tileServiceComponentName,
  CharSequence tileLabel,
  Icon icon,
  Executor resultExecutor,
  Consumer<Integer> resultCallback
)

La devolución de llamada contiene información sobre si se agregó o no la tarjeta agregado, si ya estaba allí o si se produjo algún error.

Usa tu criterio cuando decidas cuándo y con qué frecuencia enviar mensajes a los usuarios. Mié se recomienda llamar a requestAddTileService() solo en contexto, como Cuando el usuario interactúa por primera vez con una función que facilita tu tarjeta.

El sistema puede optar por dejar de procesar solicitudes para un ComponentName si el usuario lo rechazó suficientes veces El El usuario se determina a partir del Context que se usa para recuperar esto. servicio, debe coincidir con el usuario actual.