In my app I have the following structure:
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name=".DeepLinkActivity"
android:exported="true"
android:launchMode="singleInstancePerTask">
<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:host="myhost"
android:path="/mypath"
android:scheme="myscheme" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- activity_deep_link.xml -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
tools:navGraph="@navigation/my_nav_graph" />
</FrameLayout>
// DeepLinkActivity.kt
class DeepLinkActivity : AppCompatActivity() {
private lateinit var binding: ActivityDeepLinkBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDeepLinkBinding.inflate(layoutInflater)
setContentView(binding.root)
setUpNavigationGraph()
}
private fun setUpNavigationGraph() {
val navHostFragment = supportFragmentManager
.findFragmentById(binding.navHostFragment.id) as NavHostFragment
val navController = navHostFragment.navController
val navGraph = navController.navInflater
.inflate(R.navigation.my_nav_graph)
.apply {
this.setStartDestination(R.id.notTheStartDestinationFragment)
}
val startDestinationArgs = bundleOf(
"someRequiredArgumentHere" to false
)
navController.setGraph(navGraph, startDestinationArgs)
}
}
When I open that activity through deep linking via ADB (adb shell am start -d myscheme://myhost/mypath
), the activity is started normally.
But when I start it via the Chrome App the app crashes:
Caused by: java.lang.IllegalArgumentException: Required argument "someRequiredArgumentHere" is missing and does not have an android:defaultValue
Obs.: I'm using the Safe Args plugin.
What am I doing wrong and why the behavior differs?
I just found out why the startDestinationArgs
is being ignored while navigating via browser.
If we check the internal code of NavController#setGraph(NavGraph, Bundle?)
, NavController#onGraphCreated(Bundle?)
will only use the startDestinationArgs
if no deep link happened.
As a workaraound, before setting up my nav graph, I just clear the activity's intent (but that's probably not the best way to resolve that problem)