Habilitar Web Share Target en Trusted Web Activity

Web Share Target permite que las PWA reciban contenido compartido de otras aplicaciones instaladas en el dispositivo. Esta función puede ser utilizada, por ejemplo, por aplicaciones como editores de imágenes para recibir una imagen de una app de cámara o una red social para recibir una imagen o un video para compartir.

A partir de Chrome 86, Web Share Target también está disponible para las aplicaciones que usan Trusted Web Activity. Si bien la PWA debería funcionar de inmediato, se requieren algunos cambios en la aplicación para Android.

En este artículo, se supone que el desarrollador está familiarizado con las Trusted Web Activities. Los lectores que no estén familiarizados con la tecnología pueden comenzar con la Guía de integración.

Del mismo modo, una explicación completa de la implementación de Web Share Target en una PWA está fuera del alcance, y los desarrolladores pueden encontrar más información en este artículo.

La aplicación de demostración en https://scrapbook-pwa.web.app/ se usará como la PWA para este artículo, y su código fuente está disponible en GitHub. La aplicación para Android se basa en la demostración básica de Trusted Web Activity.

Agrega Web Share Target a la app para Android

Para modificar una aplicación existente basada en Trusted Web Activity para implementar Web Share Target, se requieren modificaciones en tres archivos diferentes:

build.gradle

Se actualizó la biblioteca android-browser-helper con compatibilidad para Web Share Target. Como primer paso, actualiza la aplicación para usar una versión superior o igual a 2.0.1.

dependencies {
    ...
    implementation 'com.google.androidbrowserhelper:androidbrowserhelper:2.2.0'
}

res/strings.xml

La aplicación debe indicarle a la Trusted Web Activity los detalles del uso compartido que admite recibir, como las URLs que se deben abrir, el método que se usará y los tipos MIME admitidos.

Esto se hace a través de un JSON, que se pone a disposición de la Trusted Web Activity con un recurso de cadena. Los campos son los mismos que el campo share_target disponible en el manifiesto web y se pueden agregar a una cadena dentro de strings.xml, casi tal como está, con dos notas importantes:

  1. El valor del atributo de acción debe ser la URL completa, incluido el origen.
  2. Se deben escapar las comillas dobles, por lo que cada " se convierte en \".

Así se ve la sección share_target de https://googlechrome.github.io/samples/scrapbook-pwa/manifest.json así:

{
  ...
  "share_target": {
    "action": "/_share-target",
    "enctype": "multipart/form-data",
    "method": "POST",
    "params": {
      "files": [{
        "name": "media",
        "accept": [
          "audio/*",
          "image/*",
          "video/*"
        ]
      }]
    }
  },
  ...
}

El nuevo elemento de cadena se verá de la siguiente manera:

<string name="share_target">
{
    \"action\": \"https://twa-web-scrapbook.web.app/_share-target\",
    \"method\": \"POST\",
    \"enctype\": \"multipart/form-data\",
    \"params\": {
      \"files\": [{
          \"name\": \"media\",
          \"accept\": [\"image/*\", \"audio/*\", \"video/*\"]
      }]
    }
}
</string>

AndroidManifest.xml

Se requieren algunos cambios en el manifiesto de Android. Primero, debemos asegurarnos de que se declare, exporte y habilite el DelegationService.

Los desarrolladores que crearon su aplicación en función de la demostración básica ya tendrán incluido el servicio, y el lenguaje de marcado debería estar dentro de la etiqueta de la aplicación y verse de la siguiente manera:

<service
    android:name="com.google.androidbrowserhelper.trusted.DelegationService"
    android:enabled="true"
    android:exported="true">

    <intent-filter>
        <action android:name="android.support.customtabs.trusted.TRUSTED_WEB_ACTIVITY_SERVICE"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</service>

Por último, se deben agregar dos elementos nuevos a la etiqueta de actividad LauncherActivity: - Una etiqueta meta-data que hace referencia al JSON definido en strings.xml. - Un intent-filter que declara qué tipos MIME puede controlar la aplicación en otras apps del dispositivo.

<meta-data
    android:name="android.support.customtabs.trusted.METADATA_SHARE_TARGET"
    android:resource="@string/share_target"/>

<intent-filter>
    <action android:name="android.intent.action.SEND" />
    <action android:name="android.intent.action.SEND_MULTIPLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="audio/*" />
    <data android:mimeType="image/*" />
    <data android:mimeType="video/*" />
</intent-filter>

Como se puede ver en el lenguaje de marcado anterior, se debe agregar un elemento data para cada mime-type declarado en el JSON share_target.

Conclusión

La integración de Web Share Target permite que las PWA dentro de una Trusted Web Activity se integren más profundamente con otras aplicaciones instaladas en un dispositivo Android.

Como se describe en los pasos anteriores, el lenguaje de marcado adicional necesario para agregar compatibilidad con la API en una app para Android existente que usa Trusted Web Activity se simplifica con android-browser-helper.

Consulta el artículo de Web Share Target para obtener más información sobre el uso de la API en una PWA y la API de Web Share para aprender a compartir contenido desde la app web progresiva.

Solución de problemas

Mi aplicación no aparece como una opción cuando intento compartir un archivo desde otra aplicación.

Cuando la aplicación no aparece como una opción, esto indica que el intent-filter es incorrecto. Vuelve a verificar el lenguaje de marcado intent-filter y asegúrate de que contenga las acciones, la categoría y los mime-types correctos que controla la aplicación.

Mi aplicación aparece como una opción, se inicia la PWA, pero no se comparten los datos.

Hay algunas cosas que pueden causar esto. Esta es una lista de tareas para verificar:

  • Asegúrate de que la validación de Vínculos de recursos digitales se realice correctamente.
  • Verifica que el JSON dentro de strings.xml sea correcto.