Cómo crear vínculos directos para un destino

En Android, un vínculo directo te lleva directamente a un destino específico dentro de una app.

El componente de Navigation te permite crear dos tipos diferentes de vínculos directos: implícito y explícito.

Cómo crear un vínculo directo explícito

Un vínculo directo explícito es una instancia única de un vínculo directo que usa un PendingIntent para dirigir a los usuarios a una ubicación específica dentro de tu app. Por ejemplo, puedes mostrar un vínculo directo explícito como parte de una notificación o un widget de la app.

Cuando un usuario abre tu app con un vínculo directo explícito, la pila de actividades de la tarea se borra y se reemplaza con el destino del vínculo directo. Cuando se anidan gráficos, el destino de inicio de cada nivel de anidamiento, es decir, el destino de inicio de cada elemento <navigation> de la jerarquía, también se agrega a la pila. Esto significa que, cuando un usuario presiona el botón Atrás desde un destino de vínculo directo, navega hacia atrás en la pila de navegación como si hubiera ingresado a tu app desde su punto de entrada.

Puedes usar la clase NavDeepLinkBuilder para construir un PendingIntent, como se muestra en el siguiente ejemplo. Ten en cuenta que, si el contexto proporcionado no es un Activity, el constructor usa PackageManager.getLaunchIntentForPackage(), si está disponible, como la actividad predeterminada para el lanzamiento.

Kotlin

val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .createPendingIntent()

Java

PendingIntent pendingIntent = new NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .createPendingIntent();

De forma predeterminada, NavDeepLinkBuilder inicia el vínculo directo explícito en la Activity de lanzamiento predeterminado que se declara en el manifiesto de tu app. Si tu NavHost está en otra actividad, debes especificar el nombre de su componente cuando crees el compilador de vínculos directos:

Kotlin

val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .setComponentName(DestinationActivity::class.java)
    .createPendingIntent()

Java

PendingIntent pendingIntent = new NavDeepLinkBuilder(context)
        .setGraph(R.navigation.nav_graph)
        .setDestination(R.id.android)
        .setArguments(args)
        .setComponentName(DestinationActivity.class)
        .createPendingIntent();

Si tienes un objeto ComponentName, puedes pasarlo directamente al compilador:

Kotlin

val componentName = ...

val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .setComponentName(componentName)
    .createPendingIntent()

Java

ComponentName componentName = ...;

PendingIntent pendingIntent = new NavDeepLinkBuilder(context)
        .setGraph(R.navigation.nav_graph)
        .setDestination(R.id.android)
        .setArguments(args)
        .setComponentName(componentName)
        .createPendingIntent();

Si tienes un NavController existente, también puedes crear un vínculo directo mediante NavController.createDeepLink().

Cómo crear un vínculo directo implícito

Un vínculo directo implícito hace referencia a un destino específico en una app. Cuando se invoca un vínculo directo, por ejemplo, cuando un usuario hace clic en un vínculo, Android puede abrir tu app en el destino correspondiente.

Los vínculos directos también pueden coincidir con URI, acciones de intent y tipos de MIME. Puedes especificar varios tipos de concordancia para un vínculo directo, pero ten en cuenta que primero se priorizan los argumentos del URI, le sigue la acción y, luego, el tipo de MIME.

Este es un ejemplo de un vínculo directo que contiene un URI, una acción y un tipo de MIME:

<fragment android:id="@+id/a"
          android:name="com.example.myapplication.FragmentA"
          tools:layout="@layout/a">
        <deepLink app:uri="www.example.com"
                app:action="android.intent.action.MY_ACTION"
                app:mimeType="type/subtype"/>
</fragment>

También puedes usar el editor de Navigation para crear un vínculo directo implícito a un destino de la siguiente manera:

  1. En la pestaña Design del editor de Navigation, selecciona el destino del vínculo directo.
  2. Haz clic en + en la sección Deep Links del panel Attributes.
  3. En la ventana Add Deep Link, ingresa la información del vínculo directo.

    Ten en cuenta lo siguiente:

    • Se supone que los URI sin esquema son http o https. Por ejemplo, www.google.com coincide con http://www.google.com y con https://www.google.com.
    • Los marcadores de posición de los parámetros de ruta de acceso en forma de {placeholder_name} coinciden con uno o más caracteres. Por ejemplo, http://www.example.com/users/{id} coincide con http://www.example.com/users/4. El componente de Navigation intenta analizar los valores del marcador de posición en tipos adecuados. Para ello, hace coincidir los nombres de los marcadores con los argumentos definidos para el destino del vínculo directo. Si no se define ningún argumento con el mismo nombre, se utiliza un tipo predeterminado String para el valor del argumento. Puedes usar el comodín .* para hacer coincidir 0 o más caracteres.
    • Los marcadores de posición de los parámetros de consulta se pueden usar en lugar de los parámetros de ruta o junto con ellos. Por ejemplo, http://www.example.com/users/{id}?myarg={myarg} coincide con http://www.example.com/users/4?myarg=28.
    • No es necesario que los marcadores de posición de los parámetros de consulta para variables definidas con valores predeterminados o anulables coincidan. Por ejemplo, http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2} coincide con http://www.example.com/users/4?arg2=28 o http://www.example.com/users/4?arg1=7. Este no es el caso con los parámetros de ruta. Por ejemplo, http://www.example.com/users?arg1=7&arg2=28 no coincide con el patrón anterior, ya que no se proporciona el parámetro de ruta de acceso necesario.
    • Los parámetros de búsqueda adicionales no afectan la coincidencia del URI del vínculo directo. Por ejemplo, http://www.example.com/users/{id} coincide con http://www.example.com/users/4?extraneousParam=7, aunque extraneousParam no está definido en el patrón del URI.
  4. (Opcional) Marca la opción Auto Verify a fin de solicitar a Google que verifique que eres el propietario del URI. Para obtener más información, consulta el artículo Cómo verificar Android App Links.

  5. Haz clic en Add. Aparece un ícono de vínculo sobre el destino seleccionado para indicar que el destino tiene un vínculo directo.

  6. Haz clic en la pestaña Code para cambiar a la vista XML. Se agregó un elemento <deepLink> anidado al siguiente destino:

    <deepLink app:uri="https://www.google.com" />
    

Para habilitar los vínculos directos implícitos, también debes hacer adiciones al archivo manifest.xml de tu app. Agrega un solo elemento <nav-graph> a una actividad que apunte a un gráfico de navegación existente, como se muestra en el siguiente ejemplo:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication">

    <application ... >

        <activity name=".MainActivity" ...>
            ...

            <nav-graph android:value="@navigation/nav_graph" />

            ...

        </activity>
    </application>
</manifest>

Cuando compilas tu proyecto, el componente de Navigation reemplaza el elemento <nav-graph> con elementos <intent-filter> generados para hacer coincidir todos los vínculos directos del gráfico de navegación.

Cuando se activa un vínculo directo implícito, el estado de la pila de actividades depende de si el Intent implícito se lanzó con la marca Intent.FLAG_ACTIVITY_NEW_TASK:

  • Si la marca está configurada, la pila de actividades de la tarea se borra y se reemplaza con el destino del vínculo directo. Al igual que con los vínculos directos explícitos, cuando se anidan gráficos, también se agrega a la pila el destino de inicio de cada nivel de anidamiento, es decir, el destino de inicio de cada elemento <navigation> de la jerarquía. Esto significa que, cuando un usuario presiona el botón Atrás desde un destino de vínculo directo, navega hacia atrás en la pila de navegación como si hubiera ingresado a tu app desde su punto de entrada.
  • Si no se configura la marca, permaneces en la pila de tareas de la app anterior donde se activó el vínculo directo implícito. En este caso, el botón Atrás te hace retroceder a la app anterior, mientras que el botón Arriba inicia la tarea de tu app en el destino jerárquico principal dentro de tu gráfico de navegación.

Cómo administrar vínculos directos

Se recomienda usar siempre el launchMode predeterminado de standard cuando uses Navigation. Cuando se usa el modo delanzamiento standard, Navigation administra automáticamente los vínculos directos llamando a handleDeepLink() para procesar cualquier vínculo directo explícito o implícito dentro del Intent. Sin embargo, esto no sucede automáticamente si se vuelve a usar Activity cuando se usa un launchMode alternativo, como singleTop. En este caso, es necesario llamar de forma manual a handleDeepLink() en onNewIntent(), como se muestra en el siguiente ejemplo:

Kotlin

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    navController.handleDeepLink(intent)
}

Java

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    navController.handleDeepLink(intent);
}

Recursos adicionales

Si deseas obtener más información sobre la navegación, consulta los siguientes recursos.

Codelabs

Videos