I still haven't figured out a way to do it with explicit deep links, but I settled for a solution which leverages implicit deep link.
First, add a deep link to your fragment in the nav graph XML.
<deepLink android:id="@+id/deepLink"
app:uri="my-app://com.example.app/hotspot?ssid={ssid}&passkey={passkey}" />
Add the <nav-graph /> tag within your <activity /> in the manifest. This will ensure that all the intent filters are created and merged to your manifest.
<nav-graph android:value="@navigation/primary_app_nav" />
Create your PendingIntent for the notification as follows.
fun getNotificationPendingIntent(ssid: String, passkey: String): PendingIntent {
val uri = Uri.parse("my-app://com.example.app/hotspot?ssid=$ssid&passkey=$passkey")
val bundle = Bundle().apply { putParcelable(SHARE_DEEP_LINK_KEY, uri) }
val intent = Intent(this, SailsActivity::class.java).apply {
putExtras(bundle)
// to clear the back stack
addFlags(FLAG_ACTIVITY_CLEAR_TOP or FLAG_ACTIVITY_SINGLE_TOP
or FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK)
}
return PendingIntent.getActivity(this, launchShareSheetCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
Finally, you need to handle the deep link intents from your Activity class' onCreate() method.
private fun handleDeepLinkIntent() {
val deepLink = intent.extras?.getParcelable(SHARE_DEEP_LINK_KEY) as? Uri
deepLink?.also {
val intent = Intent(this, SenderService::class.java)
this.bindService(intent, serviceConn, Context.BIND_ABOVE_CLIENT)
navigateDeepLink(it)
}
}
private fun navigateDeepLink(uri: Uri) {
findNavController(R.id.navHostFragment).apply {
if (graph.hasDeepLink(uri))
navigate(uri)
else {
currentDestination?.getAction(id)?.let {
navigate(id)
}
}
}
}
Deep link URI arguments are automatically available to you in the destination fragment.
if (arguments != null) {
val ssid = requireArguments().getString("ssid")
val passkey = requireArguments().getString("passkey")
}