Parent Navigation has always been a tough topic on Android. There are not a lot of apps that implement the guidelines correctly, maybe because they are hard to understand or complicated to implement. Even the Google apps don’t implement them: it’s always frustrating to take a screenshot, press Up on the preview and not be redirected to the Google Photo app 😞.
Unlike the Back button, which should come back to the previous screen – even if that screen was not from the same app –, the Up button should stay in the same app.
Let’s see how to implement this navigation.
Here is a simple music app, with 3 activities:
Forward navigation is pretty obvious:

On MainActivity, users can go to AlbumActivity or TrackActivity.
Nothing special here. So what about back navigation?

Since we’re in the same task, Up navigation and Back navigation do the same thing: they come back to the previous activity. But if we don’t start from the main activity (for instance from a notification or a widget), Up and Back won’t have the same behavior:

No need to write anything in the Activity#onOptionsItemSelected method! Everything is already done in the Android SDK.
We mainly just need to edit the AndroidManifest.xml file to add some attributes to our activities.
parentActivityNameFirst, we need to declare a parent activity for each child activity:
TrackActivity will come back to AlbumActivity, which itself comes back to MainActivity.
<activity
android:name=".AlbumActivity"
android:parentActivityName=".MainActivity"
... />
<activity
android:name=".TrackActivity"
android:parentActivityName=".AlbumActivity"
... />See also : getParentActivityIntent
But that’s not enough: now when pressing the Up button a new activity is created – even if we’re in the same task –, instead of dimissing the current activity.
launchModeBy declaring parent activities’ launchMode as singleTop, we prevent the system from creating a new activity each time we press Up.
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
...>
...
</activity>
<activity
android:name=".AlbumActivity"
android:launchMode="singleTop"
... />Now we have the desired behavior, but we don’t cover all the cases. What if I start TrackActivity from outside the app, and press Up? I want to be redirected to AlbumActivity.
TrackActivity is not redirect to AlbumActivity when pressing Up. Mildly frustrating, to say the least.
To do that, we have to declare a taskAffinity.
taskAffinityDeclaring a taskAffinity for TrackActivity allows a new task to be created when starting this activity from outside the app. Thanks to that, Up navigation will switch to the main task and create an AlbumActivity.
Curious about how it works? See Activity#onNavigateUp
<activity
android:name=".TrackActivity"
android:taskAffinity=".Track"
.../>One issue here: AlbumActivity needs to know which album we want to display.
onPrepareSupportNavigateUpTaskStackOn TrackActivity, we need to override onPrepareSupportNavigateUpTaskStack to edit the intent that will start the parent activity when pressing Up:
override fun onPrepareSupportNavigateUpTaskStack(builder: TaskStackBuilder) {
super.onPrepareSupportNavigateUpTaskStack(builder)
val albumId = intent.getLongExtra(TrackActivity.EXTRA_ALBUM_ID, -1L)
val albumIntent = AlbumActivity.create(this, albumId)
builder.editIntentAt(builder.intentCount - 1)?.putExtras(albumIntent)
}See also onCreateNavigateUpTaskStack.
TrackActivity is now redirected to AlbumActivity when pressing Up. 👌
One last thing: because we create a new task when starting TrackActivity from outside the app, TrackActivity will remain on the Recents screen when pressing Up. It would be great to remove it automatically.
TrackActivity is still visible in the Recents screen. Not very useful.
autoRemoveFromRecentsWith autoRemoveFromRecents, the activity will be removed from the Recents screen when its task is completed, for instance when coming back to the parent activity.
<activity
android:name=".TrackActivity"
android:autoRemoveFromRecents="true"
.../>
TrackActivity is no more visible in the Recents screen. 🙌
To sum up, this is what the AndroidManifest.xml looks like:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".AlbumActivity"
android:label="@string/album_title"
android:launchMode="singleTop"
android:parentActivityName=".MainActivity" />
<activity
android:name=".TrackActivity"
android:autoRemoveFromRecents="true"
android:label="@string/track_title"
android:parentActivityName=".AlbumActivity"
android:taskAffinity=".Track" />Now that you know how to tune the AndroidManifest to get a satisfying parent navigation, please don’t just finish() the activity when pressing Up 😀