Search code examples
androidandroid-architecture-navigationandroid-navigation-graphandroid-deep-link

Android deep link ignores popUpTo


Our app uses the OpenId AppAuth lib for login. The initial fragment and some info-dialogs are contained in nav_graph_login. After successful login, the user is forwarded to a dashboard, which is inside nav_graph_main, using the app:popUpTo=@id/nav_graph_login and app:popUpToInclusive="true" to remove the login fragments from the backstack. So, tapping the "back" button on the dashboard closes the app. Works well!

From the dashboard, the user can navigate to different "details" fragments.

However, if we deep link to one of the details fragments, the nav_graph_login remains in the backstack. Clicking the "back" button on the dashboard will show the login screen. This is unintended. I guess this is caused by this from here:

As with explicit deep linking, when nesting graphs, the start destination from each level of nesting—that is, the start destination from each element in the hierarchy—is also added to the stack.

Does anyone have an idea, how to avoid this behavior on deep links?

We handle deep links in the MainActivity

class MainActivity {
  override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    // there is more logic here, but for the sake of this post, I keep it simple
    navController.handleDeepLink(intent)
  }
}

main_activity.xml

<androidx.constraintlayout.widget.ConstraintLayout
    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/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph_login" />

</androidx.constraintlayout.widget.ConstraintLayout>

nav_graph_login:

<navigation 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:id="@+id/nav_graph"
    app:startDestination="@id/welcomeScreenFragment">

  <include app:graph="@navigation/nav_graph_main" />

  <fragment
        android:id="@+id/welcomeScreenFragment"
        android:name="my.app.WelcomeScreenFragment"
        android:label="WelcomeScreenFragment">
    <action
            android:id="@id/action_dashboard"
            app:destination="@id/nav_graph_main"
            app:popUpTo="@id/nav_graph_login"
            app:popUpToInclusive="true" />
  </fragment>
</navigation>

nav_graph_main:

<navigation 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:id="@+id/nav_graph_main"
    app:startDestination="@id/dashboard">

  <action
        android:id="@+id/action_dashboard"
        app:destination="@id/nav_graph_main"
        app:popUpTo="@id/nav_graph"
        app:popUpToInclusive="true" />

  <fragment
        android:id="@+id/dashboard"
        android:name="my.app.Dashboard">
    <action
      android:id="@+id/action_dashboardFragment_to_details1Fragment"
      app:destination="@id/details1" />
  </fragment>

  <fragment
        android:id="@+id/details1"
        android:name="my.app.Details1Fragment">
    <deepLink
      android:id="@+id/deepLinkToDetails1"
      app:uri="a-host.net/details/{id}" />
  </fragment>

</navigation>


Solution

  • As discussed here, navController.handleDeepLink(intent) is responsible for restarting the Activity. The linked thread also contains possible solutions.