Open Composables via notification with Jetpack Navigation

Igor Escodro
ProAndroidDev
Published in
3 min readMar 26, 2021

--

Handling screen navigation is a complex task in any framework. Luckily we already have a great tool for helping in this flow, but some different scenarios may need more attention. One of these scenarios is opening the application on a specific Composable in Jetpack Compose.

The Jetpack Navigation Compose is an awesome tool: it uses a solid base from the default Jetpack Navigation for View System with the flexibility needed to handle Composable.

When developing the Navigation Graph in this new library, we create a Composable function similar to this one below, informing the destinations and arguments to navigate in our application. For more information on how to get started with Jetpack Navigation Compose, please access the official docs.

Back to the View System Jetpack Navigation, when creating PendingIntent for notifications, the code was similar to:

However, as we can notice, the code from our Navigation Graph migrated from XML to Kotlin and some of the parameters (like graph and destinations ids) passed to NavDeepLinkBuilder do not make sense anymore.

For more information about PendingIntent, please access the clarifying article by Nicole Borrelli.

Deep links to the rescue

The library supports implicit deep links to help the navigation between Composables, associating a specific URL, action and/or mime-type. In order to add this support to our Composable, we add a new parameter to it, deepLinks:

In the example above, we created a simple URI (https://example.com) and concat a subdirectory (/task_id=) to open the screen in a specific task, based on the id parameter ({task_id}).

Now, we have two alternatives on how to handle the deep link call in our notification.

Set the ComponentName to the Activity in the Intent

The first alternative is to set the Activity in the ComponentName when creating the Intent. This will link the URI that we are passing in the Intent with the Activity containing our Navigation Graph.

This is a nice approach when the notification and the Activity containing the Navigation Graph are in the same module. If they are separate or do not have the visibility needed, then we have a second alternative.

Add an intent-filter to match the deep link

In case the Activity and the notification code are not in the same module, we can add a proper intent-filter to match our deep link declared in the Navigation Graph.

After declaring the intent-filter in the AndroidManifest.xml, the notification code can create our PendingIntent similar to:

This time we do not set the Context and the Activity, because the intent-filter will handle this communication for us.

How to test the deep links

Deep link needs to be well defined in order to work. If you have some issues (like I did), I suggest using Android Device Bridge to validate if the deep link is correctly set before integrating in your notification, which usually is harder to test multiple times.

In order to test your deep link and intent-filter, run the following command:

adb shell am start -W -a android.intent.action.VIEW -d “https://example.com/task_id=35”

Running this command will open the Composable that we registered earlier with this deep link. If it does not work or open the start destination, probably something needs to be updated.

For more information about deep links in Android, please access the official docs.

Final thoughts

It is great to already have a tool as powerful as Jetpack Navigation Compose in the beginning of Jetpack Compose. It allows navigation handling in a familiar way and already has support for ton of features.

I recently updated the notification feature in my personal application to this new approach. So if you want to dig deeper in more real scenario code, please access the pull request below.

Thanks a lot for Ian Lake for sharing his thoughts in Slack channel, as well as sharing some great demo for this scenario. ❤️

--

--

Passionate Android developer | Google Developer Expert for Android