Cómo proporcionar objetivos de Direct Share

Figura 1: Fila de Direct Share en Sharesheet, como se muestra en 1

Usa los objetivos de Direct Share para que los usuarios de otras apps puedan compartir URLs, imágenes y otros tipos de datos con tu app de manera más fácil y rápida. Para ello, presenta los 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 forma 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 yChooserTargets en esta página.

Cómo publicar objetivos de Direct Share

La fila de Direct Share de Sharesheet solo muestra atajos dinámicos que proporciona la API de accesos directos de uso compartido. Para publicar objetivos de Direct Share, completa los siguientes pasos.

  1. 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>
    
  2. Cuando se inicialice la app, usa setDynamicShortcuts para ordenar los atajos dinámicos por importancia.

    Un índice más bajo indica más importancia. Si creas una app de comunicación, estas pueden ser las conversaciones principales ordenadas por fecha más reciente a medida que aparecen en tu app. No publiques atajos que estén inactivos; una conversación sin actividad del usuario en los últimos 30 días se considera inactiva.

    Kotlin

    ShortcutManagerCompat.setDynamicShortcuts(myContext, listOf(shortcut1, shortcut2, ..))
    

    Java

    List<ShortcutInfoCompat> shortcuts = new ArrayList<>();
    shortcuts.add(shortcut1);
    shortcuts.add(shortcut2);
    ...
    ShortcutManagerCompat.setDynamicShortcuts(myContext, shortcuts);
    
    
  3. Si estás desarrollando una app de comunicación, informa el uso de atajos mediante pushDynamicShortcut inmediatamente cada vez que el usuario reciba o envíe un mensaje a un contacto. Para obtener más información, consulta Cómo informar el uso de atajos para las apps de comunicación en esta página. Por ejemplo, informa el uso de los mensajes enviados por el usuario especificando vinculaciones de funciones en el acceso directo mediante ShortcutInfoCompat.Builder#addCapabilityBinding con la función 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);
    
  4. Si el usuario borra un contacto, usa removeLongLivedShortcut. Esta es la forma preferida de quitar el acceso directo, sin importar si los servicios del sistema lo almacenaron 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 las clasificaciones de tus objetivos de Direct Share

Android Sharesheet muestra una cantidad fija de objetivos de Direct Share. Estas sugerencias se ordenan por rango. Si deseas mejorar la clasificación de tus accesos directos, haz lo siguiente:

  • Asegúrate de que todos los shortcutIds sean únicos y nunca se reutilicen para diferentes objetivos.
  • Asegúrate de que el acceso directo sea permanente. Para ello, llama a setLongLived(true).
  • En el caso de los atajos relacionados con conversaciones, informa el uso de atajos para mensajes salientes y entrantes. Para ello, vuelve a publicar los atajos correspondientes en ShortcutManagerCompat.pushDynamicShortcut. Consulta Cómo informar el uso de accesos directos para las apps de comunicación en esta página para obtener más detalles.
  • Evita proporcionar objetivos de Direct Share irrelevantes o inactivos, por ejemplo, contactos a los que el usuario no 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 posible spam. Es muy poco probable que los usuarios compartan en esas conversaciones.
  • Llama a setCategories() para asociar el acceso directo con los atributos mimeType adecuados. Por ejemplo, en el caso de una app de SMS, si el contacto no está habilitado para RCS o MMS, no debes asociar el acceso directo correspondiente con tipos de MIME que no sean de texto, como image/* y video/*.
  • Para una conversación determinada, una vez que se envía un atajo dinámico y se informa el uso, no cambies el ID del atajo. Esto garantiza la retención de los datos de uso para la clasificación.

Si el usuario presiona cualquier objetivo de Direct Share, la app debe llevarlo a una IU en la que pueda realizar una acción directamente en el objeto del objetivo. No le muestres 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, si presionas un objetivo de Direct Share, el usuario pasa a una vista de conversación con la persona seleccionada. El teclado es 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 brindan 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. Para obtener más información, consulta Cómo declarar un objetivo de uso compartido. Este campo es obligatorio para las combinaciones de teclas que se usarán como objetivos de uso compartido.
setLongLived()

Especifica si un acceso directo es válido o no cuando la app anula su publicación o lo oculta (ya sea un acceso directo dinámico o fijo). Si un acceso directo es de larga duración, varios servicios del sistema pueden almacenarlo en la caché, incluso en el caso de que se anule su publicación como acceso directo dinámico.

Hacer que un acceso directo sea permanente puede mejorar su clasificación. Para obtener más información, consulta Cómo obtener la mejor clasificación.

setShortLabel(), setLongLabel()

Cuando publiques un acceso directo para una persona en particular, incluye su nombre completo en setLongLabel() y cualquier nombre corto, como un sobrenombre o un nombre, en setShortLabel().

Consulta un ejemplo de publicación de accesos directos de uso compartido en GitHub.

Cómo proporcionar imágenes de accesos directos

Para crear un acceso directo de uso compartido, tendrás que agregar una imagen mediante setIcon().

Los accesos directos de uso compartido pueden aparecer en todas las superficies del sistema y modificarse. Además, algunos dispositivos con las versiones 7, 8 o 9 de Android (niveles de API 25, 26, 27 y 28) pueden mostrar íconos solo de mapa de bits sin 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 los íconos adaptables. La forma más común de lograr esto es ajustar el mapa de bits cuadrado previsto a 72 x 72 dp y centrarlo dentro de un lienzo transparente de 108 x 108 dp. Si el ícono incluye regiones transparentes, debes incluir un color de fondo. De lo contrario, las regiones transparentes aparecerán de color negro.

No proporciones imágenes enmascaradas en una forma específica. Por ejemplo, en Android 10 (nivel de API 29), era común proporcionar avatares de usuarios para objetos ChooserTarget de Direct Share que estaban enmascarados en un círculo. Android Sharesheet y otras superficies del sistema de Android 10 ahora proporcionan formas y temas a las imágenes de accesos directos. El método preferido para proporcionar accesos directos de uso compartido, a través de ShortcutManagerCompat, da forma automáticamente a los objetos ChooserTarget de Direct Share para los 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 será similar al siguiente:

<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 objetivo 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 ShortcutManagerCompat. Como es un intent diferente, Intent.EXTRA_SHORTCUT_ID no estará disponible, por lo que deberás pasar el ID de forma manual si lo necesitas.

Cómo informar el uso de combinaciones de teclas para las apps de comunicación

Si estás desarrollando una app de comunicación, puedes mejorar tu clasificación en Android Sharesheet informando el uso de los mensajes salientes y entrantes. Para hacerlo, vuelve a publicar el acceso directo de la conversación que representa al contacto mediante ShortcutManagerCompat.pushDynamicShortcut.

El uso de atajos y las vinculaciones de funciones son retrocompatibles con Android 5.0 (nivel de API 21).

Informar el uso de accesos directos para mensajes salientes

El uso de informes 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 los informes de uso, especifica las vinculaciones de funciones en el acceso directo mediante ShortcutInfoCompat.Builder#addCapabilityBinding con la función 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 valor del parámetro Audience, ya que el tipo recipient está asociado con la capability.

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

Cómo informar el uso de atajos para los mensajes entrantes

Para activar los informes de uso cuando el usuario recibe un mensaje como un SMS o un mensaje de chat, un correo electrónico o notificaciones, además debes especificar vinculaciones de funciones en el acceso directo a través de ShortcutInfoCompat.Builder#addCapabilityBinding con la función actions.intent.RECEIVE_MESSAGE.

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 proviene de un chat en grupo, también debes agregar el valor del parámetro Audience, ya que el tipo sender está asociado con la capability.

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

Usa 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 conjunto meta-data + chooser-target-service + intent-filters. Consulta la API ChooserTargetService de Direct Share actual.

Este servicio ya está declarado en la biblioteca de compatibilidad, por lo que el usuario no necesita declarar el servicio en el manifiesto de la app. No obstante, se debe tener en cuenta el vínculo de la actividad de uso compartido con el servicio como proveedor de selección de objetivos.

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 los accesos directos y cómo salen del dispositivo?

Los accesos directos se almacenan por completo en el dispositivo, en el directorio de datos del sistema, en una partición de disco encriptada. Solo los servicios del sistema y la misma app que los publica, 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 ChooserTargetService. Los resultados se recuperaban de manera reactiva a pedido, lo que hacía que los objetivos se cargaran lentamente.

En Android 10 (nivel de API 29), reemplazamos las APIs de ChooserTargetService de Direct Share 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 prepara ShareSheet. El mecanismo ChooserTargetService de Direct Share seguirá funcionando, pero el sistema clasifica los objetivos que se proporcionan de esta manera en menor medida que los que usen la API de accesos directos de uso compartido.

Android 11 (nivel de API 30) dio de baja 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 de selector (el uso típico de accesos directos cuando se mantienen presionados los íconos de las apps 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 selector heredados).

¿Cuál es la orientación sobre la cantidad de accesos directos de uso compartido que se debe publicar?

La cantidad de accesos directos de uso compartido está restringida al mismo límite de accesos directos dinámicos disponibles mediante getMaxShortcutCountPerActivity(android.content.Context). Puedes publicar cualquier número hasta ese límite, pero debes tener en cuenta que los accesos directos de uso compartido pueden estar visibles en el selector de aplicaciones, manteniendo presionado y en la hoja para compartir. La mayoría de los selectores de aplicaciones que 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 cómo compartir accesos directos.