Android - Clear task flag not working for PendingIntent
Solution 1
if u r using solution 1 then Just remove the launchMode="singleTask"
from manifest
1)
final Intent notificationIntent = new Intent(mContext, ActivityA.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(myContext, 0, notificationIntent, 0);
OR
2)
<activity
android:name=".ActivityA"
android:theme="@style/theme_noActionBar"
android:noHistory="true">
OR
3)
<activity android:name=".ActivityA" android:launchMode="singleTop">
Solution 2
I had loads of problems with this, and thought I was going crazy until I uninstalled/reinstalled my App and hey presto, the code works as per many posts on Stack Overflow. I was doing the following:
Intent i = new Intent(getApplicationContext(), MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
and was continually getting two versions of the App. After an uninstall on one device, and re-starting the other device everything now behaves as expected with a single instance. Hope this helps you.
Solution 3
The problem you are encountering has to do with Android creating a new task using your PendingIntent
and the required Intent.FLAG_ACTIVITY_NEW_TASK
. In other words, the flags you are wanting to use have to do with starting activities within the context of a given task stack. A PendingIntent
usually does not have a context, and therefore what you are seeing is a task being created for your Activity A pending intent.
Here's the reference to the docs:
The requirement for the first in a series of PendingIntent
s to have Intent.FLAG_ACTIVITY_NEW_TASK
is the issue. Note that a series of pending intents can have the same context as the initial pending intent using the "getActivities" method.
You are correct that it is not possible to do what you want only using flags. Your code is correct, and to get the behavior that you want you will need too look beyond intent flags.
There are many other ways, such as using the manifest, running a service, using static fields, etc. to try to manage what you are interested in doing. Besides that, you could possibly use TaskStackBuilder
to solve your problem if you decide to go the route of using the Manifest. There are also many other solutions not involving flags, but you specifically asked about using flags.
Solution 4
You can set the launchMode
of ActivityA to singleTask
in Manifest file. Since ActivityA
is the root of your application it works.
From documentation:
The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one.
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
EDIT 1:
Since you don't want to modify Manifest file, only option I can see is using Intent.makeRestartActivityTask method to generate the Intent. However this will relaunch the ActivityA rather than resuming existing instance.
Intent intent = Intent.makeRestartActivityTask(new ComponentName(this, ActivityA.class));
PendingIntent rIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
Solution 5
A solution in terms of intent flag would be as following:
- In Manifest, add
launchMode:singleTask
for Activity A -
Use the following code block:
final Intent notificationIntent = new Intent(mContext, ActivityA.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent contentIntent = PendingIntent.getActivity(myContext, 0, notificationIntent, 0);
What happens here is that when Activity A is launched using notification, by the definition of Intent.FLAG_ACTIVITY_NEW_TASK
, since there exists a task A>B>C containing A, this task is brought forward also destroying the activities B and C and A starts with the onNewIntent --> onRestart --> onStart --> onResume
If a task is already running for the activity you are now starting, that task is brought to the foreground with its last state restored and the activity receives the new intent in
onNewIntent()
Now the reason, why it doesn't behave nicely with just the intent flags is that, the Activity A wasn't launched with singleTask
mode and Android somehow doesn't maintain the state of it.
Related videos on Youtube
Admin
Updated on October 01, 2022Comments
-
Admin over 1 year
I have a task stack of A > B > C. I am currently on C, and then I press the home button. I get a notification with the intent to take me to Activity A. I press the notification, and I'm at A but if I press back, I go to C, then B, then A.
I am setting up my PendingIntent like so. Anything clearly wrong with it?
final Intent notificationIntent = new Intent(mContext, ActivityA.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent contentIntent = PendingIntent.getActivity(myContext, 0, notificationIntent, 0);
EDIT 1:
I tried the suggestion here: Clear all activities in a task?
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
but I still get the same result. My activity A starts in my application task stack, I press back and go to C, then B, then A again.
I am starting to think that this is either not possible in Android or it's not possible when using a pending intent.
EDIT 2: This is not a matter of what flags are needed. More of an issue of what could be going wrong that the flags seem to have no effect.
-
Dan S over 9 yearsTo be clear you want to return to A with B and C removed from the stack?
-
Admin over 9 yearsI want to return to A with B and C removed, but I'm not sure if I just want A to resume or A to be removed as well, and a new instance of A to start.
-
Admin over 9 years@DanS either way. I NEED B and C to be cleared. I will inspect the behavior of A when I can get the clearing to happen.
-
Dan S over 9 yearsIn
ActivityA
do you haveonNewIntent()
implemented? -
Admin over 9 years@DanS Nope. I haven't heard of that method, but I'd like to focus on clearing B and C properly from the stack.
-
Dan S over 9 yearsThat method will be called to handle the formerly pending
Intent
. Try a simple implementation to see if that will fix your stack problem. -
Admin over 9 years@DanS Sorry. Can you elaborate by "try a simple implementation"?
-
Dan S over 9 yearsLet us continue this discussion in chat.
-
matiash over 9 years@user2676468 Just to clarify, have you tried the
NEW_TASK | CLEAR_TOP
combination, with no other flags? -
Admin over 9 yearsYes. I got the same behavior as mentioned in my question.
-
Vaishali Sutariya over 9 yearsfinal Intent notificationIntent = new Intent(mContext, ActivityA.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent contentIntent = PendingIntent.getActivity(myContext, 0, notificationIntent, 0);
-
Vaishali Sutariya over 9 years@user2676468 thank you :)
-
Jim over 9 yearsHave the same issue, did you found a solution ?
-
Admin over 9 years@Jim nope. Still super confused how this doesn't seem to be possible.
-
user2297550 about 5 yearsStrangely enough, uninstalling and reinstalling the app made the original code work (CLEAR_TOP | NEW_TASK), as suggested by one of the obscure answers to this question below. If you can confirm it, please accept it to save a lot of people a lot of trouble.
-
-
Admin over 9 yearsJust tried it. Same behavior as mentioned in my question.
-
Admin over 9 yearsThis could work, but in case I ever wanted to change my pending intent to Activity B, then setting single task would give me an issue. I should be able to set an Intent.FLAG to do this without modifying the manifest.
-
Newtz over 8 yearsOption 2 worked for me, option 1 didn't help at all in my situation
-
ashraful over 6 yearsOption 2 woked for me
-
Miha_x64 almost 6 yearsOption 1 works for me only when Intent has non-null action. Why?!
-
Miha_x64 almost 6 years...or when
PendingIntent
has non-zerorequestCode
. -
Vlad over 5 years
makeRestartActivityTask
works like a charm! Thanks -
user2297550 about 5 yearsuninstalling and reinstalling the app made the OP's original code work for me, as suggested by one of the obscure answers below (CLEAR_TOP | NEW_TASK)
-
Daniel Wilson over 4 yearsI don't know why but this is the only option that works for me. I have an activity launched by an external app expecting a result, and use NFC + pending intents in my own app which was totally breaking the result setting my app does when I just use NEW_TASK.
-
Flyview about 4 yearsMine also needed a restart for the new Intent.FLAG_ACTIVITY_CLEAR_TOP to work!
-
Harmen almost 4 yearsMethod 3 did it for me.
-
Houssem Chlegou over 3 yearslegacy answers never gets old! :D it drive me crazy also, and restarting the app is what made it working. Thanks a lot for sharing this.
-
uzaysan over 3 yearsYes Uninstalling and reinstalling solved my problem.
-
mehul bisht about 2 yearsnon-zero request code did it for me! :)