Usa objetivos de Direct Share para que los usuarios de otras apps puedan compartir URLs, imágenes o cualquier otro tipo de datos con tu app de forma más fácil y rápida. Direct Share funciona presentando contactos de apps de mensajería y redes sociales directamente en Android Sharesheet, sin que los usuarios tengan que seleccionar la app y, luego, buscar el contacto.
ShortcutManagerCompat
es una API de AndroidX que proporciona accesos directos de uso compartido y que es retrocompatible con la API ChooserTargetService obsoleta. Esta es la manera preferida de publicar accesos directos de uso compartido y ChooserTargets. Para obtener instrucciones,
consulta Cómo usar AndroidX para proporcionar accesos directos de uso compartido y ChooserTargets
en esta página.
Cómo publicar objetivos de Direct Share
La fila de Direct Share de Sharesheet solo muestra los accesos directos dinámicos que proporciona la API de accesos directos de uso compartido. Para publicar objetivos de Direct Share, sigue estos pasos.
En el archivo de recursos XML de tu app, declara elementos
share-target.<shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <share-target android:targetClass="com.example.android.sharingshortcuts.SendMessageActivity"> <data android:mimeType="text/plain" /> <category android:name="com.example.android.sharingshortcuts.category.TEXT_SHARE_TARGET" /> </share-target> </shortcuts>Cuando se inicialice tu app, usa
setDynamicShortcutspara ordenar los accesos directos dinámicos por importancia.Un índice más bajo indica mayor importancia. Si creas una app de comunicación, pueden ser las conversaciones principales ordenadas por antigüedad, tal como aparecen en tu app. No publiques accesos directos obsoletos. Se considera obsoleta una conversación sin actividad del usuario en los últimos 30 días.
Kotlin
ShortcutManagerCompat.setDynamicShortcuts(myContext, listOf(shortcut1, shortcut2, ..))
Java
List<ShortcutInfoCompat> shortcuts = new ArrayList<>(); shortcuts.add(shortcut1); shortcuts.add(shortcut2); ... ShortcutManagerCompat.setDynamicShortcuts(myContext, shortcuts);
Si desarrollas una app de comunicación, informa el uso de accesos directos a través de
pushDynamicShortcutinmediatamente cada vez que el usuario reciba o envíe un mensaje a un contacto. Consulta Informa el uso de accesos directos para apps de comunicación en esta página para obtener más información. Por ejemplo, informa el uso de los mensajes que envía el usuario especificando vinculaciones de capacidades en el acceso directo a través deShortcutInfoCompat.Builder#addCapabilityBindingcon laactions.intent.SEND_MESSAGEcapacidad.Kotlin
val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.SEND_MESSAGE").build() ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)
Java
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.SEND_MESSAGE") .build(); ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);
Si el usuario borra un contacto, usa
removeLongLivedShortcut. Esta es la manera preferida de quitar el acceso directo, independientemente de si los servicios del sistema lo almacenan en caché. En el siguiente fragmento de código, se muestra un ejemplo de cómo hacerlo.Kotlin
val deleteShortcutId = "..." ShortcutManagerCompat.removeLongLivedShortcuts(myContext, listOf(deleteShortcutId))
Java
String deleteShortcutId = "..."; ShortcutManagerCompat.removeLongLivedShortcuts( myContext, Arrays.asList(deleteShortcutId));
Mejora la clasificación de tus objetivos de Direct Share
Android Sharesheet muestra una cantidad fija de objetivos de Direct Share. Estas sugerencias se ordenan por clasificación. Para mejorar la clasificación de tus accesos directos, puedes hacer lo siguiente:
- Asegúrate de que todos los
shortcutIdssean únicos y nunca se vuelvan a usar para diferentes objetivos. - Para asegurarte de que el acceso directo sea permanente, llama a
setLongLived(true). - En el caso de los accesos directos relacionados con conversaciones, informa el uso de accesos directos
para mensajes salientes y entrantes volviendo a publicar los accesos directos correspondientes
a través de
ShortcutManagerCompat.pushDynamicShortcut. Consulta Informa el uso de accesos directos para apps de comunicación en esta página para obtener más detalles. - Evita proporcionar objetivos de Direct Share irrelevantes o obsoletos, por ejemplo, contactos a los que el usuario no les envió mensajes en los últimos 30 días.
- En el caso de las apps de SMS, evita proporcionar accesos directos para códigos cortos o conversaciones identificadas como spam potencial. Es muy poco probable que los usuarios compartan contenido en esas conversaciones.
- Llama a
setCategories()para asociar el acceso directo con los atributosmimeTypeadecuados. Por ejemplo, en el caso de una app de SMS, si el contacto no tiene habilitados los servicios RCS o MMS, no asociarías el acceso directo correspondiente con tipos MIME que no sean de texto, comoimage/*yvideo/*. - Para una conversación determinada, una vez que se envía un acceso directo dinámico y se informa el uso, no cambies el ID del acceso directo. Esto garantiza la retención de los datos de uso para la clasificación.
Si el usuario presiona cualquier objetivo de Direct Share, tu app debe llevarlo a una IU en la que pueda realizar una acción directamente sobre el tema del objetivo. No le presentes al usuario una IU de desambiguación ni lo coloques en una IU que no esté relacionada con el objetivo presionado. Por ejemplo, en una app de mensajería, presionar un objetivo de Direct Share lleva al usuario a una vista de conversación con la persona que seleccionó. El teclado está visible y el mensaje se completa previamente con los datos compartidos.
API de accesos directos de uso compartido
A partir de Android 10 (nivel de API 29),
ShortcutInfo.Builder agregó métodos y mejoras
que proporcionan información adicional sobre el objetivo de uso compartido:
setCategories()- A partir de Android 10, las categorías también se usan para filtrar los accesos directos que pueden controlar intents o acciones de uso compartido. Consulta Cómo declarar un objetivo de uso compartido para obtener más detalles. Este campo es obligatorio para los accesos directos que se usarán como objetivos de uso compartido.
setLongLived()Especifica si un acceso directo es válido cuando la app lo anula o lo hace invisible (como un acceso directo dinámico o fijado). Si un acceso directo es permanente, varios servicios del sistema pueden almacenarlo en caché incluso después de que se anule como acceso directo dinámico.
Hacer que un acceso directo sea permanente puede mejorar su clasificación. Consulta Obtén la mejor clasificación para obtener más detalles.
setShortLabel(),setLongLabel()Cuando publiques un acceso directo para una persona, incluye su nombre completo en
setLongLabel()y cualquier nombre corto, como un apodo o un nombre, ensetShortLabel().
Consulta un ejemplo de publicación de accesos directos de uso compartido en GitHub.
Proporciona imágenes de accesos directos
Para crear un acceso directo de uso compartido, deberás agregar una imagen a través de setIcon().
Los accesos directos de uso compartido pueden aparecer en las superficies del sistema y es posible que se les cambie la forma.
Además, es posible que algunos dispositivos que ejecutan versiones de Android 7, 8 o 9 (niveles de API 25, 26, 27 y 28) muestren íconos solo de mapa de bits sin un fondo, lo que disminuye drásticamente el contraste. Para asegurarte de que tu acceso directo se vea como corresponde,
proporciona un mapa de bits adaptable con IconCompat.createWithAdaptiveBitmap().
Asegúrate de que los mapas de bits adaptables sigan las mismas pautas y dimensiones configuradas para íconos adaptables. La forma más común de lograr esto es escalar el mapa de bits cuadrado deseado a 72 x 72 dp y centrarlo dentro de un lienzo transparente de 108 x 108 dp. Si tu ícono incluye regiones transparentes, debes incluir un color de fondo; de lo contrario, las regiones transparentes aparecerán en negro.
No proporciones imágenes enmascaradas en una forma específica. Por ejemplo, antes de Android 10 (API nivel 29), era común proporcionar avatares de usuario para ChooserTargets de Direct Share que estaban enmascarados en un círculo. Android Sharesheet y otras superficies del sistema de Android 10 ahora ofrecen formas y temas para las imágenes de accesos directos.
El método preferido para proporcionar accesos directos de uso compartido, a través
ShortcutManagerCompat,
da forma automáticamente para brindar retrocompatibilidad con objetos ChooserTarget de Direct Share para
círculos.
Cómo declarar un objetivo de uso compartido
Los objetivos de uso compartido deben declararse en el archivo de recursos de la app, de manera similar a las definiciones de accesos directos estáticos. Agrega definiciones de objetivos de uso compartido dentro del elemento raíz <shortcuts> en el archivo de recursos,
junto con otras definiciones de accesos directos estáticos. Cada elemento <share-targets>
contiene información sobre el tipo de datos compartidos, las categorías coincidentes y la
clase de destino que controlará el intent de uso compartido. El código XML se ve de la siguiente manera:
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <share-target android:targetClass="com.example.android.sharingshortcuts.SendMessageActivity"> <data android:mimeType="text/plain" /> <category android:name="com.example.android.sharingshortcuts.category.TEXT_SHARE_TARGET" /> </share-target> </shortcuts>
El elemento de datos en un objetivo de uso compartido es similar al de la especificación de datos en un filtro de intents. Cada objetivo de uso compartido puede tener varias categorías, que solo se usan para hacer coincidir los accesos directos publicados de una app con sus definiciones de objetivos de uso compartido. Las categorías pueden tener cualquier valor arbitrario definido por la app.
Si el usuario selecciona un acceso directo de uso compartido en Android Sharesheet que coincide con el objetivo del ejemplo anterior, la app obtendrá el siguiente intent de uso compartido:
Action: Intent.ACTION_SEND ComponentName: {com.example.android.sharingshortcuts / com.example.android.sharingshortcuts.SendMessageActivity} Data: Uri to the shared content EXTRA_SHORTCUT_ID: <ID of the selected shortcut>
Si el usuario abre el objetivo de uso compartido desde los accesos directos del selector, la app obtendrá
el intent que se haya creado al agregar el acceso directo de uso compartido a la
ShortcutManagerCompat.
Como es un intent diferente, Intent.EXTRA_SHORTCUT_ID no estará disponible y deberás pasar el ID de forma manual si lo necesitas.
Informa el uso de accesos directos para apps de comunicación
Si desarrollas una app de comunicación, puedes mejorar tu clasificación en Android Sharesheet informando el uso de mensajes salientes y entrantes.
Para ello, vuelve a publicar el acceso directo de conversación que representa el contacto a través de
ShortcutManagerCompat.pushDynamicShortcut.
El uso de accesos directos y las vinculaciones de capacidades son retrocompatibles con Android 5.0 (API 21).
Informa el uso de accesos directos para mensajes salientes
Informar el uso de los mensajes que envía el usuario es funcionalmente similar a hacer clic en el botón "Enviar" después de crear un mensaje.
Para activar la generación de informes de uso, especifica vinculaciones de capacidades en el acceso directo
a través de ShortcutInfoCompat.Builder#addCapabilityBinding
con la capacidad actions.intent.SEND_MESSAGE.
Kotlin
val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.SEND_MESSAGE").build() ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)
Java
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.SEND_MESSAGE") .build(); ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);
Si el mensaje saliente es para un chat en grupo, también debes agregar el Audience valor del parámetro, ya que el recipient tipo está asociado con la capacidad.
Kotlin
val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(groupShortTitle) .setLongLabel(groupLongTitle) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.SEND_MESSAGE", "message.recipient.@type", listOf("Audience")).build() ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)
Java
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(groupShortTitle) .setLongLabel(groupLongTitle) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.SEND_MESSAGE", "message.recipient.@type", Arrays.asList("Audience")) .build(); ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);
Informa el uso de accesos directos para mensajes entrantes
Para activar la generación de informes de uso cuando el usuario recibe un mensaje, como un SMS, un mensaje de chat, un correo electrónico o notificaciones, también debes especificar vinculaciones de capacidades
en el acceso directo a través de
ShortcutInfoCompat.Builder#addCapabilityBinding con
la actions.intent.RECEIVE_MESSAGE capacidad.
Kotlin
val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE").build() ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)
Java
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE") .build(); ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);
Si el mensaje entrante es de un chat en grupo, también debes agregar el Audience valor del parámetro, ya que el sender tipo está asociado con la capacidad.
Kotlin
val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(groupShortTitle) .setLongLabel(groupLongTitle) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE", "message.sender.@type", listOf("Audience")).build() ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)
Java
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier) ... .setShortLabel(groupShortTitle) .setLongLabel(groupLongTitle) .setCategories(matchedCategories) .setLongLived(true) .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE", "message.sender.@type", Arrays.asList("Audience")) .build(); ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);
Cómo usar AndroidX para proporcionar accesos directos de uso compartido y ChooserTargets
Para poder trabajar con la biblioteca de compatibilidad de AndroidX, el manifiesto de la app debe contener el servicio de destino del selector de metadatos y el conjunto de filtros de intents. Consulta
la API de ChooserTargetService Direct Share actual.
Este servicio ya está declarado en la biblioteca de compatibilidad, por lo que el usuario no necesita declararlo en el manifiesto de la app. Sin embargo, se debe tener en cuenta el vínculo de la actividad de uso compartido al servicio como proveedor de destino del selector.
En el siguiente ejemplo, la implementación de ChooserTargetService es
androidx.core.content.pm.ChooserTargetServiceCompat y ya está definida
en AndroidX:
<activity android:name=".SendMessageActivity" android:label="@string/app_name" android:theme="@style/SharingShortcutsDialogTheme"> <!-- This activity can respond to Intents of type SEND --> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <!-- Only needed if you import the sharetarget AndroidX library that provides backwards compatibility with the old DirectShare API. The activity that receives the Sharing Shortcut intent needs to be taken into account with this chooser target provider. --> <meta-data android:name="android.service.chooser.chooser_target_service" android:value="androidx.sharetarget.ChooserTargetServiceCompat" /> </activity>
Preguntas frecuentes sobre accesos directos de uso compartido
¿Cómo se almacenan los datos de uso de accesos directos y salen del dispositivo?
Los accesos directos se almacenan por completo integrado en el dispositivo en el directorio de datos del sistema en una partición de disco encriptada. Los servicios del sistema y la misma app que publica los accesos directos solo pueden acceder a la información de los accesos directos, como el ícono, el intent y los nombres de las personas y los recursos.
¿Cuál es el historial de Direct Share?
Presentamos Direct Share en Android 6.0 (nivel de API 23) para permitir que las apps proporcionen objetos ChooserTarget a través de un ChooserTargetService. Los resultados se recuperaban de manera reactiva a pedido, lo que generaba un tiempo de carga lento para los objetivos.
En Android 10 (nivel de API 29), reemplazamos las APIs de Direct Share ChooserTargetService por la nueva API de accesos directos de uso compartido. En lugar de obtener resultados de manera reactiva a pedido, la API de accesos directos de uso compartido permite que las apps publiquen objetivos de Direct Share con anticipación. Esto aceleró rápidamente el proceso de recuperación de objetivos de Direct Share cuando se preparaba Sharesheet. El mecanismo de Direct Share ChooserTargetService seguirá funcionando, pero el sistema clasifica los objetivos que se proporcionan de esta manera más abajo que cualquier objetivo que use la API de accesos directos de uso compartido.
Android 11 (nivel de API 30) dejó de usar el servicio ChooserTargetService, y la API de accesos directos de uso compartido es la única forma de proporcionar objetivos de Direct Share.
¿En qué se diferencian los accesos directos publicados para objetivos de uso compartido de los accesos directos del selector (el uso típico de accesos directos cuando se mantiene presionado el ícono de la app en el selector)?
Los accesos directos que se publiquen para un "objetivo de uso compartido" también serán accesos directos del selector y se mostrarán en el menú cuando se mantenga presionado el ícono de tu app. El límite máximo de accesos directos por actividad también se aplica a la cantidad total de accesos directos que publica una app (incluye objetivos de uso compartido y accesos directos de Launcher heredados).
¿Cuál es la guía sobre la cantidad de accesos directos de uso compartido que se deben publicar?
La cantidad de accesos directos de uso compartido está restringida al mismo límite de accesos directos dinámicos
disponibles a través de
getMaxShortcutCountPerActivity(android.content.Context). Se puede publicar cualquier número hasta ese límite, pero se debe tener en cuenta que los accesos directos de uso compartido pueden estar visibles en el selector de apps cuando se mantiene presionado y en la hoja de uso compartido. La mayoría de los selectores de apps cuando se mantienen presionados muestran un máximo de cuatro o cinco accesos directos en modo vertical y ocho en modo horizontal. Consulta estas
preguntas frecuentes
para obtener más detalles y orientación sobre los accesos directos de uso compartido.