Android navigation component passing argument with safeArgs and deep link

Viewed 5272

I have a navigation xml for a feature as below -

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_featureB.xml"
    app:startDestination="@id/FragmentB">

    <fragment
        android:id="@+id/FragmentB"
        android:name="FragmentB"
        android:label="FragmentB">
        <deepLink app:uri="App://FragmentB" />
    </fragment>
</navigation>

In my FeatureA fragment, I do the following -

val uri = Uri.parse("App://FragmentB")
findNavController().navigate(uri)

I know how to use safeArgs without deep link. How do I pass data to other feature with deep link?

2 Answers

You can do the following

First add argument in navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_featureB.xml"
    app:startDestination="@id/FragmentB">

    <fragment
        android:id="@+id/FragmentB"
        android:name="FragmentB"
        android:label="FragmentB">
        <argument
            android:name="yourarg"
            android:defaultValue="Argument Default Value"/>
        <deepLink app:uri="App://FragmentB/{yourarg}" />
    </fragment>
</navigation>

Then you can call it like this

val args = Bundle()
args.putString("yourarg", "Argument Value")

val deeplink = findNavController().createDeepLink()
               .setDestination(R.id.FragmentB)
               .setArguments(args)
               .createPendingIntent()
val builder = NotificationCompat.Builder(
                context, "deeplink")
                .setContentTitle("Deep link with data")
                .setContentText("Deep link with data to Android")
                .setSmallIcon(R.drawable.ic_android)
                .setContentIntent(deeplink)
                .setAutoCancel(true)
val notificationManager =
                context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(0, builder.build())

EDITED

Without Notification

First, add argument in navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_featureB.xml"
    app:startDestination="@id/FragmentB">

    <fragment
        android:id="@+id/FragmentB"
        android:name="FragmentB"
        android:label="FragmentB">
        <argument
            android:name="yourarg"
            android:defaultValue="Argument Default Value"/>
        <deepLink app:uri="App://FragmentB/{yourarg}" />
    </fragment>
</navigation>

Then you can call it like this

val uri = Uri.parse("App://FragmentB/yourarg")
findNavController().navigate(uri)

Then you can get the argument with this code

val argument = arguments?.getString("yourarg")

// Or with Safe Args

val safeArgs: FragmentBArgs by navArgs()
val yourarg = safeArgs.yourarg

References : https://codelabs.developers.google.com/codelabs/android-navigation#9

Above answers shows how to works with string data types. But if you want to pass custom objects, safe-args also works well;

<fragment
    android:id="@+id/verification_fragment"
    android:name="com.appname.ui.verification.VerificationFragment"
    android:label="VerificationFragment">
    <argument
        android:name="verificationType"
        android:defaultValue="PHONE"
        app:argType="com.appname.core.model.VerificationType" />
    <deepLink app:uri="android-app://com.appname/verification_fragment?verificationType={verificationType}" />
</fragment>

Pass custom attributes to deeplink;

            val request = NavDeepLinkRequest.Builder
            .fromUri("android-app://appname/verification_fragment?verificationType=${VerificationType.MAIL}".toUri())
            .build()
        findNavController().navigate(request)

Read attributes from destination fragments;

private val args: VerificationFragmentArgs by navArgs()

args.verificationType
Related