JetPack Compose Navigation: Deep Links

[Fuente: https://developer.android.com/codelabs/jetpack-compose-navigation?hl=en#7]

Enable deep link support

In addition to adding arguments, you can also add deep links to associate a specific URL, action, and/or mime type with a composable. In Android, a deep link is a link that takes you directly to a specific destination within an app. Navigation Compose supports implicit deep links. When an implicit deep link is invoked—for example, when a user clicks a link—Android can then open your app to the corresponding destination.

In this section, you’ll add a new deep link for navigating to the SingleAccountScreen composable with a corresponding account type and enable this deep link to be exposed to external apps as well. To refresh your memory, the route for this composable was "single_account/{account_type}" and this is what you’ll also use for the deep link, with some minor deep link related changes.

Since exposing deep links to external apps isn’t enabled by default , you must also add <intent-filter> elements to your app’s manifest.xml file, so this will be your first step.

Start by adding the deep link to the app’s AndroidManifest.xml. You need to create a new intent filter via <intent-filter> inside of the <activity>, with the action VIEW and categories BROWSABLE and DEFAULT.

Then inside the filter, you need the data tag to add a scheme (rally – name of your app) and host (single_account – route to your composable) to define your precise deep link. This will give you rally://single_account as the deep link URL.

Note that you don’t need to declare the account_type argument in the AndroidManifest. This will be appended later inside the NavHost composable function.

<activity
    android:name=".RallyActivity"
    android:windowSoftInputMode="adjustResize"
    android:label="@string/app_name"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <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="rally" android:host="single_account" />
    </intent-filter>
</activity>

Now you can react to the incoming intents from within RallyActivity.

The composable SingleAccountScreen accepts arguments already, but now it also needs to accept the newly created deep link to launch this destination when its deep link is triggered.

Inside the composable function of SingleAccountScreen, add one more parameter deepLinks. Similarly to arguments, it also accepts a list of navDeepLink, as you could define multiple deep links leading to the same destination. Pass the uriPattern, matching the one defined in intent-filter in your manifest – rally://singleaccount, but this time you’ll also append its accountTypeArg argument:

import androidx.navigation.navDeepLink
// ...

composable(
    route = SingleAccount.routeWithArgs,
    // ...
    deepLinks = listOf(navDeepLink {
        uriPattern = "rally://${SingleAccount.route}/{${SingleAccount.accountTypeArg}}"
    })
)

You know what’s next, right? Move this list into RallyDestinations SingleAccount:

object SingleAccount : RallyDestination {
    // ...
    val arguments = listOf(
        navArgument(accountTypeArg) { type = NavType.StringType }
    )
    val deepLinks = listOf(
       navDeepLink { uriPattern = "rally://$route/{$accountTypeArg}"}
    )
}

And again, replace it in the corresponding NavHost composable:

// ...
composable(
    route = SingleAccount.routeWithArgs,
    arguments = SingleAccount.arguments,
    deepLinks = SingleAccount.deepLinks
) {...}

Now your app and SingleAccountScreen are ready to handle deep links. To test that it behaves correctly, do a fresh install of Rally on a connected emulator or device, open a command line and execute the following command, to simulate a deep link launch:

adb shell am start -d "rally://single_account/Checking" -a android.intent.action.VIEW

This will take you directly into the “Checking” account, but you can also verify it works correctly for all other account types.