How to preserve current back stack (or task) when notification is clicked?
Asked Answered
G

5

10

In my application, I create a notification which starts Details Activity. I want to add this activity to top of current task (or back stack). For example I expect application task (back stack) to behave like this:

enter image description here

but I get this:

enter image description here

I have not used FLAG_ACTIVITY_CLEAR_TASK and FLAG_ACTIVITY_NEW_TASK flags. What should I do?

Edit: First picture is just an example. I think the the question's title is completely explicit. I want to add Details Activity on top of current stack, and not to start with a new task.

This is how I create the PendingIntent:

    // Details activity intent
    Intent intent = new Intent(context, DetailsActivity.class);
    intent.putExtra(Com.KEY_ID, event.getId());
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
            intent, PendingIntent.FLAG_UPDATE_CURRENT);

And this is the manifest:

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name_system"
        android:launchMode="singleTop"
        android:theme="@style/AppTheme.NoActionBar">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity
        android:name=".NoteActivity"
        android:label="@string/app_name_system"
        android:theme="@style/AppTheme.NoActionBar"
        android:windowSoftInputMode="stateHidden" />

    <activity
        android:name=".DetailsActivity"
        android:launchMode="singleTop"
        android:label="@string/app_name_system"
        android:theme="@style/AppTheme.NoActionBar" />
Gaff answered 9/2, 2017 at 17:14 Comment(5)
Did you try setting the flags Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP for the intent?Portwine
@Portwine I did it now, but no result.Gaff
Did you solve that? I have same issue too. Whenever I start activity from notification it clears my current back stack.Dalenedalenna
@AndreiVinogradov Not exactly, but I've managed to solve the problem using task affinity. Read my answer below.Gaff
Yeah, it's not exactly the same, but I also found that your way is the closest to required behavior. Please, accept your own answer to make the topic more clear.Dalenedalenna
G
4

I found this link: Preserving Navigation when Starting an Activity. Although it does not provide the exact solution for my question, but it produces the desired result.

The link describes that we should start DetailsActivity in a new task with a different affinity.

Manifest:

    <activity
        android:name=".DetailsActivity"
        android:excludeFromRecents="true"
        android:label="@string/app_name_system"
        android:launchMode="singleTop"
        android:taskAffinity=""
        android:theme="@style/AppTheme.NoActionBar" />

PendingIntent creation:

    Intent intent = new Intent(context, DetailsActivity.class);
    intent.putExtra(Com.KEY_ID, event.getId());
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
            intent, PendingIntent.FLAG_UPDATE_CURRENT);
Gaff answered 9/2, 2017 at 19:42 Comment(0)
C
2

You can use PendingIntent.getActivities instead of PendingIntent.getActivity to build you stack.

Intent mainActivityIntent = new Intent(context,MainActivity.class);
mainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Intent noteActivityIntent= new Intent(context,NoteActivity.class);
noteActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Intent detailActivityIntent= new Intent(context,DetailActivity.class);

final PendingIntent pendingIntent = PendingIntent.getActivities(ctx, UNIQUE_REQUEST_CODE++,
            new Intent[] {mainActivityIntent,noteActivityIntent,detailActivityIntent},PendingIntent.FLAG_UPDATE_CURRENT);

This should solve your purpose.

Refer this link for more details Back to main activity from notification-created activity

Coreligionist answered 9/2, 2017 at 17:45 Comment(2)
I think this is the way to go, but I've appended some more explanations to the questions. I want to add DetailsActivity to current stack, whatever it was. I think you solution always gives Main > Note > Details. Is that so?Gaff
Yes, my solution will always give this stack-- Main > Note > Details.It actually starts up new DetailActivity with two activity intent in back stack.Those two intent will be fired and will create two new activity instances on back button press.This will however not add activity to the current stack.Coreligionist
C
1

You need to use getActivities() and specify the entire navigation path in the third argument which accepts an array of intents. You need to construct that array in the order your app navigation should work, i.e., leftmost being the root/main activity and further down the levels from there.

Something like this

Intent mainActivityIntent = new Intent(context, MainActivity.class);
mainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // only specify new task flag for MainActivity

Intent noteActivityIntent= new Intent(context,NoteActivity.class);

Intent detailsActivityIntent = new Intent(context, DetailsActivity.class);

PendingIntent pendingIntent = PendingIntent.getActivities(context, 0,
            new Intent[] {mainActivityIntent,noteActivityIntent,detailsActivityIntent},PendingIntent.FLAG_UPDATE_CURRENT);

Note that : If your application is already active, once you press back android will take you back to your NoteActivity and then MainActivity. It will restart the activities if they are already there or create new otherwise.

Checklist answered 9/2, 2017 at 17:54 Comment(1)
The picture is just an example. I want to add DetailsActivity to top of current stack. Not to always start in Main > Note > Details.Gaff
J
0

I wanted the exact opposite (which is the default behaviour).

It turns out setting noHistory="true" or/and calling finish() on the Activity launched by the notification, keeps the existing backstack.

So basically the solution is either to not keep the Activity into the backstack or create a 'NotificationActivity' which will not be kept and will be in charge of starting the Activity you want (DetailsActivity in your example).

Jahdol answered 17/7, 2018 at 10:27 Comment(0)
S
0

A solution from the android docs could work for you. It's worked for me, but I only had a single parent-child back stack.

Manifest with parent relationships:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<!-- MainActivity is the parent for NoteActivity-->
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity" />
    ...
</activity>

<!-- NoteActivity is the parent for DetailsActivity -->
<activity
    android:name=".DetailsActivity "
    android:parentActivityName=".NoteActivity " />
    ...
</activity>

Creating the pending intent:

// Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this, DetailsActivity.class);

// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);

// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Scarrow answered 27/2, 2020 at 19:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.