Cómo administrar accesos directos

Después de crear los accesos directos, es posible que debas administrarlos durante el ciclo de vida de tu app. Por ejemplo, tal vez quieras optimizar tu app determinando con qué frecuencia los usuarios completan acciones específicas con tus accesos directos. En otro caso, puedes optar por inhabilitar un acceso directo fijado para evitar que tu app realice acciones desactualizadas o faltantes. En el caso de los accesos directos a los que se hace referencia en las conversaciones, te recomendamos que realices un seguimiento del uso para proporcionar indicadores que mejoren la clasificación de los accesos directos.

En esta página, se describen estas y otras formas comunes de administrar tus atajos.

Comportamiento de los accesos directos

En las siguientes secciones, se incluye información general sobre el comportamiento de los accesos directos, como la visibilidad, el orden de visualización y las clasificaciones.

Visibilidad de los accesos directos

Los atajos estáticos y dinámicos aparecen en un selector o asistente compatible cuando el usuario realiza un gesto o comando por voz específico. En los selectores compatibles, el gesto consiste en mantener presionado el ícono de selector de la app, pero puede ser diferente en otras apps de selector. Con el Asistente de Google, los atajos se pueden mostrar en el Asistente o iniciarse desde un comando por voz del usuario.

La clase LauncherApps proporciona APIs para que las apps de selector accedan a los accesos directos.

Como los accesos directos fijos aparecen en el selector, siempre son visibles. Solo en las siguientes situaciones se quita un acceso directo fijo del selector:

  • El usuario lo quita.
  • Se desinstaló la app asociada con el acceso directo.
  • El usuario borra los datos de una app en Configuración > Apps y notificaciones, selecciona la app y, luego, presiona Almacenamiento > Borrar almacenamiento.

Los objetivos de uso compartido son un subconjunto de los accesos directos dinámicos que aparecen en la fila de uso compartido directo de la hoja de uso compartido de Android.

Una hoja de contenido compartido de Android
Figura 1: Android Sharesheet Los destinos de uso compartido directo aparecen en la primera fila, seguidos de las apps clasificadas y, luego, las listas de apps.

Orden de visualización de los accesos directos

Cuando el selector muestra los accesos directos de una app, estos deben aparecer en el siguiente orden:

  1. Atajos estáticos: Son atajos cuyo método isDeclaredInManifest() devuelve true.
  2. Atajos dinámicos: Son atajos cuyo método ShortcutInfo.isDynamic() devuelve true.

Dentro de cada tipo de acceso directo (estático y dinámico), los accesos directos se ordenan en orden de rango creciente según ShortcutInfo.getRank. Asistente de Google también tiene en cuenta la clasificación de los atajos cuando determina los atajos contextuales que se mostrarán a los usuarios.

Las clasificaciones son números enteros secuenciales no negativos. Los accesos directos estáticos se clasifican de primero a último en el orden en que aparecen en tu archivo shortcuts.xml. En el caso de los accesos directos dinámicos, puedes actualizar las clasificaciones de los accesos directos existentes cuando llamas a updateShortcuts(Context, List), addDynamicShortcuts(Context, List), pushDynamicShortcut(Context, ShortcutInfoCompat) o setDynamicShortcuts(Context, List).

El orden de los destinos de uso compartido se basa en varios factores, como el historial de usuarios anterior, las visitas recientes, la frecuencia, la sugerencia de clasificación, el uso de la app y la prioridad establecida en la conversación asociada con un acceso directo de uso compartido. Los destinos de uso compartido creados con la API de Sharing Shortcuts tienen prioridad sobre los destinos de uso compartido producidos por ChooserTargetService, que dejó de estar disponible en Android 11. En Android 12 y versiones posteriores, los destinos de uso compartido generados por el objeto ChooserTargetService obsoleto ya no aparecerán en la hoja de uso compartido.

La mayoría de los selectores muestran un máximo de cuatro accesos directos. Para cualquier combinación de atajos estáticos y dinámicos que se definan, el selector muestra un máximo de dos atajos estáticos y dos dinámicos. Por ejemplo, si defines cuatro atajos estáticos y creas de manera programática tres atajos dinámicos, el selector mostrará los primeros dos atajos estáticos y los dos atajos dinámicos con la clasificación más alta.

Cómo administrar varios intents y actividades

Si quieres que tu app realice varias operaciones cuando el usuario active un acceso directo, puedes configurarla para que active actividades sucesivas. Para ello, puedes asignar varios intents, iniciar una actividad desde otra o establecer marcas de intents, según el tipo de acceso directo.

Cómo comenzar una actividad desde otra

Los accesos directos estáticos no pueden tener marcas de intents personalizadas. El primer intent de un acceso directo estático siempre tiene establecidos Intent.FLAG_ACTIVITY_NEW_TASK e Intent.FLAG_ACTIVITY_CLEAR_TASK. Esto significa que, cuando se ejecuta tu app, se destruyen todas las actividades existentes en ella cuando se inicia un acceso directo estático. Si no quieres este comportamiento, puedes usar una actividad de trampolín (una actividad invisible que inicia otra actividad) llamando a finish dentro de un bloque de inicio o onCreate antes de que se establezca el contenido de Compose:

  1. En AndroidManifest.xml file, incluye la asignación de atributos android:taskAffinity="" en la actividad de trampolín.

  2. En el archivo de recursos de accesos directos, haz referencia a la actividad de trampolín en el intent dentro del acceso directo estático.

Para obtener más información sobre las actividades disparadoras, consulta Cómo iniciar una actividad desde otra.

Cómo configurar marcas de intents

Puedes publicar accesos directos dinámicos con cualquier conjunto de marcas Intent. De preferencia, especifica la combinación de Intent.FLAG_ACTIVITY_SINGLE_TOP y Intent.FLAG_ACTIVITY_CLEAR_TOP en el intent del acceso directo. Esto garantiza que, si tu ComponentActivity ya está activa, se ponga en primer plano y se vuelva a usar sin destruirse, lo que permite que tu arquitectura de actividad única controle correctamente el evento de acceso directo a través de onNewIntent().

Para obtener más información sobre las tareas y los indicadores de intents, consulta Tareas y la pila de actividades.

Cómo actualizar los accesos directos

El ícono de selector de cada app puede contener, como máximo, una cantidad de accesos directos estáticos y dinámicos combinados que sea igual al valor que muestra getMaxShortcutCountPerActivity. No hay límite para la cantidad de accesos directos fijados que puede crear una app.

Cuando se fija un acceso directo dinámico, incluso si el publicador lo quita como tal, el acceso directo fijado sigue visible y se puede iniciar. Esto permite que una app tenga más de getMaxShortcutCountPerActivity accesos directos.

Considera el siguiente ejemplo, en el que se supone que el valor que devuelve getMaxShortcutCountPerActivity es 4:

  1. Una app de chat publica cuatro accesos directos dinámicos, que representan las cuatro conversaciones más recientes: c1, c2, c3 y c4.
  2. El usuario fija los cuatro accesos directos.
  3. Más tarde, el usuario inicia tres conversaciones adicionales: c5, c6 y c7. La app de publicador vuelve a publicar sus accesos directos dinámicos. La nueva lista de accesos directos dinámicos es: c4, c5, c6 y c7.

La app debe quitar c1, c2 y c3, ya que no puede mostrar más de cuatro accesos directos dinámicos. Sin embargo, c1, c2 y c3 siguen siendo accesos directos fijados a los que el usuario puede acceder y que puede iniciar.

Luego, el usuario puede acceder a un total de siete accesos directos que vinculan a actividades en la app de publicador. Esto se debe a que el total incluye la cantidad máxima de accesos directos y los tres accesos directos fijados.

  1. La app puede usar updateShortcuts(Context, List) para actualizar cualquiera de los siete accesos directos existentes. Por ejemplo, puedes actualizar este conjunto de accesos directos cuando cambien los íconos de los pares de chat.
  2. Puedes usar los métodos addDynamicShortcuts(Context, List) y setDynamicShortcuts(Context, List) para actualizar los accesos directos existentes con los mismos IDs. Sin embargo, no puedes usarlos para actualizar los accesos directos fijos no dinámicos, ya que estos dos métodos intentan convertir las listas de accesos directos dadas en accesos directos dinámicos.

No hay límite para la cantidad de accesos directos que se pueden enviar para que se muestren en las aplicaciones de asistencia, como el Asistente de Google. Usa el método pushDynamicShortcut de la biblioteca de Jetpack ShortcutManagerCompat para crear y actualizar los accesos directos que se usarán en las aplicaciones de asistencia. Además, agrega la biblioteca de integración de atajos de Google a tu app para que los vínculos dinámicos sean aptos para aparecer en el Asistente de Google.

Si quieres obtener más información sobre los lineamientos para los accesos directos a apps, incluida la actualización de accesos directos, consulta Prácticas recomendadas para los accesos directos.

Cómo procesar los cambios de la configuración regional del sistema

Las apps deben actualizar los accesos directos dinámicos y fijados cuando reciben la transmisión Intent.ACTION_LOCALE_CHANGED que indica un cambio en la configuración regional del sistema.

Cómo hacer un seguimiento del uso de los accesos directos

Para determinar las situaciones en las que aparecen los atajos estáticos y dinámicos, el selector examina el historial de activación de los atajos. En el caso de los accesos directos estáticos, puedes hacer un seguimiento de cuándo los usuarios completan acciones específicas en tu app. Para ello, llama al método reportShortcutUsed y pásale el ID de un acceso directo cuando ocurra cualquiera de los siguientes eventos:

  • El usuario selecciona el acceso directo con el ID específico.
  • Dentro de la app, el usuario completa de forma manual la acción correspondiente al mismo atajo.

Tu app hace un seguimiento del uso de los accesos directos dinámicos llamando al método pushDynamicShortcut y pasándole el ID del acceso directo cuando se produce un evento relevante. Enviar el uso de atajos dinámicos con este método permite que las aplicaciones de asistencia, como Asistente de Google, sugieran atajos relevantes a los usuarios. Debido a que el método pushDynamicShortcut informa el uso cuando se lo llama, no llames al método reportShortcutUsed para los mismos accesos directos.

En el caso de los accesos directos relacionados con conversaciones, es importante hacer un seguimiento del uso de los mensajes salientes y entrantes. Para obtener más detalles, consulta las prácticas recomendadas para personas y conversaciones.

Cómo inhabilitar accesos directos

Dado que tu app y sus usuarios pueden fijar accesos directos al selector del dispositivo, es posible que estos accesos directos fijos dirijan a los usuarios a acciones dentro de tu app que estén desactualizadas o que ya no existan. Para administrar esta situación, puedes inhabilitar los accesos directos que no quieres que los usuarios seleccionen llamando a disableShortcuts, que quita los accesos directos especificados de la lista de accesos directos estáticos y dinámicos, y, además, inhabilita las copias fijadas de estos accesos directos. También puedes usar una versión sobrecargada de este método que acepte un CharSequence como mensaje de error personalizado. Ese mensaje de error aparece cuando los usuarios intentan iniciar cualquier acceso directo inhabilitado.

Límite de frecuencia

Cuando usas los métodos setDynamicShortcuts, addDynamicShortcuts o updateShortcuts, es posible que solo puedas llamarlos una cantidad específica de veces en una app en segundo plano, es decir, una app sin actividades ni servicios en primer plano. El límite de la cantidad específica de veces que puedes llamar a estos métodos se denomina límite de frecuencia. Esta función evita que ShortcutManagerCompat consuma en exceso los recursos del dispositivo.

Cuando la limitación de frecuencia está activa, isRateLimitingActive devuelve verdadero. Sin embargo, el límite de frecuencia se restablece durante ciertos eventos, por lo que incluso las apps en segundo plano pueden llamar a los métodos ShortcutManager hasta que se vuelva a alcanzar el límite de frecuencia. Estos eventos incluyen los siguientes:

  • Una app pasa al primer plano.
  • Se cambia la configuración regional del sistema.
  • El usuario realiza la acción de respuesta intercalada en una notificación.

Si encuentras un límite de frecuencia durante el desarrollo o las pruebas, puedes seleccionar Opciones para desarrolladores > Restablecer la limitación de frecuencia de ShortcutManager en la configuración del dispositivo o ingresar el siguiente comando en adb:

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

Copia de seguridad y restablecimiento

Para permitir que los usuarios realicen operaciones de copia de seguridad y restablecimiento en tu app cuando cambien de dispositivo, incluye la asignación del atributo android:allowBackup="true" en el archivo de manifiesto de la app. Si admites la copia de seguridad y el restablecimiento, ten en cuenta los siguientes puntos sobre los accesos directos a apps:

  • Los atajos estáticos se vuelven a publicar automáticamente, pero solo después de que el usuario vuelve a instalar tu app en un dispositivo nuevo.
  • No se crean copias de seguridad de los atajos dinámicos, por lo que debes incluir lógica en tu app para volver a publicarlos cuando un usuario la abra en un dispositivo nuevo.
  • Los accesos directos fijados se restablecen automáticamente en el selector del dispositivo, pero el sistema no crea copias de seguridad de los íconos asociados con los accesos directos fijados. Por lo tanto, guarda las imágenes de los accesos directos fijados en tu app para que se puedan restablecer rápidamente en un dispositivo nuevo.

En el siguiente fragmento de código, se muestra la mejor manera de restablecer los accesos directos dinámicos de tu app y cómo verificar si se conservaron los accesos directos fijados de tu app:

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.
            }
        }
    }
    // ...
}