Los Android App Links son un tipo especial de vínculo directo que permite que las URL de tu sitio web abran inmediatamente el contenido correspondiente en tu app para Android (sin requerir que el usuario seleccione la app).
Para agregar Android App Links a tu app, define filtros de intents que abran el contenido de tu app con URL HTTP (como se describe en Cómo crear vínculos directos al contenido de la app), y verifica que posees las URL de app y del sitio web (como se describe en esta guía). Si el sistema verifica con éxito que posees las URL, automáticamente enruta esos intents de URL a tu app.
Para verificar la propiedad de tu app y tu sitio web, se requieren los siguientes pasos:
- Solicita la verificación automática del vínculo de la app en tu manifiesto. Esto le indica al sistema Android que debería verificar que tu app pertenece al dominio URL utilizado en tus filtros de intents.
- Declara la relación entre tu sitio web y tus filtros de intents. Para ello, aloja un archivo JSON de Vínculos de recursos digitales en la siguiente ubicación:
https://domain.name/.well-known/assetlinks.json
.
Puedes encontrar información relacionada en los siguientes recursos:
Diferencia entre vínculos directos y vínculos de la app
Un vínculo directo es un filtro de intents que permite a los usuarios ingresar directamente una actividad específica de tu app para Android. Cuando haces clic en uno de estos vínculos, es posible que se abra un diálogo de desambiguación, que permite al usuario seleccionar una app entre varias (incluida la tuya) que pueden administrar la URL determinada. Por ejemplo, en la figura 1, se muestra el cuadro de diálogo de desambiguación después de que el usuario hace clic en un vínculo del mapa y le pregunta si desea abrirlo en Maps o Chrome.

Figura 1: Diálogo de desambiguación
Un Android App Link es un vínculo directo basado en la URL de tu sitio web que tiene la verificación de que pertenece a tu sitio web. Por lo tanto, cuando haces clic en uno de estos vínculos, se abre tu app de inmediato, si está instalada. El diálogo de desambiguación no aparece. Sin embargo, el usuario puede cambiar su preferencia para manejar este tipo de vínculos más adelante.
En la siguiente tabla, se describen diferencias más específicas.
Vínculos directos | Vínculos de apps | |
---|---|---|
http , https o un esquema personalizado |
Requiere http o https |
|
Acción de intent | Cualquier acción | Requiere android.intent.action.VIEW |
Categoría del intent | Cualquier categoría | Requiere android.intent.category.BROWSABLE y android.intent.category.DEFAULT |
Verificación del vínculo | Nada | Requiere un archivo de Vínculos de recursos digitales en tu sitio web con HTTPS |
Experiencia del usuario | Puede mostrar un diálogo de desambiguación para que el usuario seleccione la app que desea abrir | Sin diálogo; se abre tu app para manejar los vínculos de tu sitio web |
Compatibilidad | Todas las versiones de Android | Android 6.0 y versiones posteriores |
Cómo solicitar verificación de vínculos de apps
A fin de habilitar la verificación de control de vínculos para tu app, configura android:autoVerify="true"
en cualquiera de los filtros de intents de URL web en el manifiesto de tu app que incluye la acción de intent android.intent.action.VIEW
y la categoría de intent android.intent.category.BROWSABLE
como se muestra en el siguiente fragmento de código de manifiesto:
<activity ...> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="http" android:host="www.example.com" /> <data android:scheme="https" /> </intent-filter> </activity>
Cuando android:autoVerify="true"
está presente en cualquiera de tus filtros de intents, instalar tu app en dispositivos con Android 6.0 y versiones posteriores hace que el sistema intente verificar todos los hosts asociados con las URL en cualquiera de los filtros de intents de tu app.
A continuación, se describe qué implica la verificación:
- El sistema inspecciona todos los filtros de intents que incluyen:
- Acción:
android.intent.action.VIEW
- Categorías:
android.intent.category.BROWSABLE
yandroid.intent.category.DEFAULT
- Esquema de datos:
http
ohttps
- Acción:
- Por cada nombre de host único que se encuentra en los filtros de intents anteriores, Android consulta los sitios web correspondientes para el archivo de Vínculos de recursos digitales en
https://hostname/.well-known/assetlinks.json
.
Solo si el sistema encuentra un archivo de Vínculos de recursos digitales coincidente para todos los hosts del manifiesto, establece tu app como el controlador predeterminado para los patrones de URL especificados.
Cómo admitir vínculos de apps para varios hosts
El sistema debe poder verificar cada host especificado en los elementos de datos de los filtros de intents de URL de la app en comparación con los archivos de Vínculos de recursos digitales alojados en los dominios web respectivos. Si falla alguna verificación, no se verificará que la app sea un controlador predeterminado para ninguno de los patrones de URL definidos en los filtros de intents de la app. Luego, el sistema adopta su comportamiento estándar de forma predeterminada para resolver el intent, como se describe en Cómo crear vínculos directos al contenido de la app.
Por ejemplo, la verificación de una app con los siguientes filtros de intents fallará si no se encuentra un archivo assetlinks.json
en https://www.example.com/.well-known/assetlinks.json
y https://www.example.net/.well-known/assetlinks.json
:
<application> <activity android:name=”MainActivity”> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="http" android:host="www.example.com" /> <data android:scheme="https" /> </intent-filter> </activity> <activity android:name=”SecondActivity”> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="www.example.net" /> </intent-filter> </activity> </application>
Recuerda que se fusionan todos los elementos <data>
en el mismo filtro de intents para representar todas las variaciones de sus atributos combinados. Por ejemplo, el primer filtro de intents anterior incluye un elemento <data>
que solo declara el esquema HTTPS. Sin embargo, se combina con el otro elemento <data>
para que el filtro de intents sea compatible con http://www.example.com
y https://www.example.com
.
Por lo tanto, debes crear filtros de intents separados cuando desees definir combinaciones específicas de dominios y esquemas de URI.
Cómo admitir vínculos de apps para varios subdominios
El protocolo Vínculos de recursos digitales trata los subdominios de tus filtros de intents como hosts independientes y únicos. Por lo tanto, si tu filtro de intents enumera varios hosts con subdominios diferentes, debes publicar un assetlinks.json
válido en cada dominio. Por ejemplo, el siguiente filtro de intents incluye www.example.com
y mobile.example.com
como hosts de URL de intents aceptados. Por lo tanto, un assetlinks.json
válido debe publicarse en https://www.example.com/.well-known/assetlinks.json
y https://mobile.example.com/.well-known/assetlinks.json
.
<application> <activity android:name=”MainActivity”> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="www.example.com" /> <data android:scheme="https" android:host="mobile.example.com" /> </intent-filter> </activity> </application>
Como alternativa, si declaras tu nombre de host con un comodín (como *.example.com
), debes publicar tu archivo assetlinks.json
en el nombre de host raíz (example.com
). Por ejemplo, una app con el siguiente filtro de intents pasará la verificación de cualquier subnombre de example.com
(como foo.example.com
) siempre que se publique el archivo assetlinks.json
en https://example.com/.well-
known/assetlinks.json
:
<application> <activity android:name=”MainActivity”> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="*.example.com" /> </intent-filter> </activity> </application>
Cómo declarar la asociación de sitios web
Debes publicar un archivo JSON de Vínculos de recursos digitales en tu sitio web para indicar las apps para Android que están asociadas con el sitio web y verificar los intents de URL de la app. El archivo JSON usa los siguientes campos para identificar aplicaciones asociadas:
package_name
: El ID de aplicación declarado en el archivobuild.gradle
de la app.sha256_cert_fingerprints
: Son las huellas digitales SHA256 del certificado de firma de tu app. Puedes usar el siguiente comando para generar la huella digital mediante la herramienta Keytool de Java:$ keytool -list -v -keystore my-release-key.keystore
Este campo admite varias huellas digitales, que pueden usarse para brindar compatibilidad con diferentes versiones de tu app, como depuración y compilación de producción.
En el siguiente ejemplo, el archivo assetlinks.json
otorga derechos de apertura de vínculos a una app para Android com.example
:
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }]
Cómo asociar un sitio web a varias apps
Un sitio web puede declarar asociaciones con varias apps dentro del mismo archivo assetlinks.json
. En la siguiente lista de archivos, se muestra un ejemplo de un archivo de instrucción que declara asociación con dos apps, por separado, y reside en https://www.example.com/.well-known/assetlinks.json
:
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.puppies.app", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }, { "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.monkeys.app", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }]
Distintas apps pueden manejar los vínculos para recursos diferentes en el mismo host web. Por ejemplo, la app1 puede declarar un filtro de intents para https://example.com/articles
, y la app2 puede declarar un filtro de intents para https://example.com/videos
.
Nota: Varias apps asociadas a un dominio pueden firmarse con el mismo o con diferentes certificados.
Cómo asociar varios sitios web a una sola app
Varios sitios web pueden declarar asociaciones con la misma app en sus respectivos archivos assetlinks.json
. En las siguientes listas de archivos, se muestra un ejemplo para declarar la asociación de example.com y example.net con app1. En la primera lista, se muestra la asociación de example.com con la app1:
https://www.example.com/.well-known/assetlinks.json
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.mycompany.app1", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }]
En la siguiente lista, se muestra la asociación de example.net con la app1. Solo la ubicación donde se alojan estos archivos es diferente (.com
y .net
):
https://www.example.net/.well-known/assetlinks.json
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.mycompany.app1", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }]
Publicación del archivo de verificación JSON
Debes publicar tu archivo de verificación JSON en la siguiente ubicación:
https://domain.name/.well-known/assetlinks.json
Asegúrate de lo siguiente:
- Se publica el archivo
assetlinks.json
con el tipo de contenidoapplication/json
. - Se debe poder acceder al archivo
assetlinks.json
mediante una conexión HTTPS, independientemente de si los filtros de intents de la app declaran HTTPS como el esquema de datos. - Se debe poder acceder al archivo
assetlinks.json
sin redireccionamientos (sin redireccionamientos 301 o 302), y los bots deben poder acceder a él (surobots.txt
debe permitir el rastreo de/.well-known/assetlinks.json
). - Si los vínculos de tu app admiten varios dominios de host, debes publicar el archivo
assetlinks.json
en cada dominio. Consulta Cómo admitir vínculos de apps para varios hosts. - No publiques tu app con URL de desarrollo y prueba en el archivo de manifiesto que podría no estar disponible para el público (como los archivos que solo están disponibles con una VPN). En esos casos, una solución es configurar variantes de compilación para generar un archivo de manifiesto diferente para las compilaciones de desarrollo.
Cómo probar vínculos de apps
Cuando implementas la función de vínculos de apps, debes probar la funcionalidad de vinculación para asegurarte de que el sistema pueda asociar tu app con tus sitios web y manejar las solicitudes de URI, tal como lo quieres.
Para probar un archivo de instrucciones existente, puedes usar la herramienta Generador y comprobador de listas de instrucciones.
Cómo confirmar la lista de hosts que se deben verificar
Cuando se realiza la prueba, debes confirmar la lista de hosts asociados que el sistema debe verificar para tu app. Haz una lista de todas las URL cuyos filtros de intents correspondientes incluyen los siguientes atributos y elementos:
- Atributo
android:scheme
con un valor dehttp
ohttps
- Atributo
android:host
con un patrón de URL de dominio - Elemento de acción
android.intent.action.VIEW
- Elemento de categoría
android.intent.category.BROWSABLE
Usa esta lista para comprobar que se proporcione un archivo JSON de Vínculos de recursos digitales en cada host y subdominio nombrado.
Cómo confirmar los archivos de Vínculos de recursos digitales
En cada sitio web, usa la API de Vínculos de recursos digitales para confirmar que el archivo JSON de Vínculos de recursos digitales se encuentre alojado y definido correctamente:
https://digitalassetlinks.googleapis.com/v1/statements:list? source.web.site=https://domain.name:optional_port& relation=delegate_permission/common.handle_all_urls
Prueba un intent de URL
Una vez que confirmes la lista de sitios web asociados con tu app y que hayas confirmado que el archivo JSON es válido, instala la app en tu dispositivo. Espera al menos 20 segundos a que se complete el proceso de verificación asíncrono. Usa el siguiente comando para comprobar si el sistema verificó tu app y configura las políticas de control de vínculos correctas:
adb shell am start -a android.intent.action.VIEW \ -c android.intent.category.BROWSABLE \ -d "http://domain.name:optional_port"
Comprueba las políticas de vínculos
Como parte de tu proceso de prueba, puedes comprobar la configuración actual del sistema para el control de vínculos. Usa el siguiente comando a fin de obtener una lista de políticas de control de vínculos existentes para todas las apps de tu dispositivo conectado:
adb shell dumpsys package domain-preferred-apps
Lo siguiente hace lo mismo:
adb shell dumpsys package d
Nota: Asegúrate de esperar al menos 20 segundos luego de instalar tu app para permitir que el sistema complete el proceso de verificación.
El comando muestra un listado de cada usuario o perfil definidos en el dispositivo, precedido por un encabezado en el siguiente formato:
App linkages for user 0:
Luego de este encabezado, el resultado usa el siguiente formato a fin de enumerar las configuraciones de control de vínculos para ese usuario:
Package: com.android.vending Domains: play.google.com market.android.com Status: always : 200000002
Este listado indica qué aplicaciones están asociadas con qué dominios para ese usuario:
Package
: Identifica una app por el nombre de su paquete, como se encuentra declarado en su manifiesto.Domains
: Muestra la lista completa de hosts cuyos vínculos web maneja esta app; utiliza espacios en blanco como delimitadores.Status
: Muestra la configuración actual de control de vínculos para esta app. Una app que aprobó la verificación, y cuyo manifiesto contieneandroid:autoVerify="true"
, muestra un estado dealways
. El número hexadecimal que le sigue a ese estado está relacionado con el registro de las preferencias de usuario para la vinculación de apps del sistema Android. Este valor no indica si la verificación tuvo éxito.
Nota: Si un usuario cambia la configuración de vínculos de apps antes de que se complete la verificación, puede que veas un falso positivo de una verificación exitosa, aunque esta falle. Sin embargo, esta falla es relevante si el usuario habilita explícitamente la app para abrir vínculos compatibles sin preguntar. Esto se debe a que las preferencias del usuario tienen prioridad ante la verificación programática (o la ausencia de esta). Como consecuencia, el vínculo dirige de forma directa a tu app, sin mostrar un diálogo, como si la verificación hubiese tenido éxito.
Ejemplo de comprobación
Para que tenga éxito la verificación de vínculos de apps, el sistema debe poder verificar tu app con todos los sitios web que especifiques en los filtros de intents de tu app, y que cumplan con los criterios para los vínculos de apps. En el siguiente ejemplo, se muestra la configuración de un manifiesto con varios vínculos de apps definidos:
<application> <activity android:name=”MainActivity”> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="www.example.com" /> <data android:scheme="https" android:host="mobile.example.com" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="www.example2.com" /> </intent-filter> </activity> <activity android:name=”SecondActivity”> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="account.example.com" /> </intent-filter> </activity> <activity android:name=”ThirdActivity”> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="map.example.com" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="market" android:host="example.com" /> </intent-filter> </activity> </application>
La siguiente es la lista de hosts que la plataforma intentaría verificar a partir del manifiesto anterior:
www.example.com mobile.example.com www.example2.com account.example.com
La siguiente es la lista de hosts que la plataforma no intentaría verificar a partir del manifiesto anterior:
map.example.com (it does not have android.intent.category.BROWSABLE) market://example.com (it does not have either an “http” or “https” scheme)
Para obtener más información sobre las listas de instrucciones, consulta Cómo crear una lista de instrucciones.