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 notificat
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">
Tried all suggestions from above and failed and the came up with a solution from the guideline from https://stackoverflow.com/a/24999724/4271334 and https://stackoverflow.com/a/26592562/4271334. Added following 2 lines in the manifest
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
and set the PendingIntent at NotificationCompat.Builder using
mBuilder.setContentIntent(addBackStack(mContext,intent));
where
public static PendingIntent addBackStack(final Context context, final Intent intent) {
TaskStackBuilder stackBuilder = TaskStackBuilder.create (context.getApplicationContext ());
stackBuilder.addNextIntentWithParentStack (intent);
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
return stackBuilder.getPendingIntent (0,PendingIntent.FLAG_UPDATE_CURRENT);
}
Hope someone will be helped.
Try using the Intent flag FLAG_ACTIVITY_CLEAR_TOP
instead of clearing the task. From the Intent documentation:
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.
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.
I created a demo project as your description and it works just as what you want.
I don't know how do you get the notification, so in my project I use a BroadcastReceiver to get a Broadcast and then show the Notification in the onReceive() method of the Receiver. I think you can compare my demo with your project to find the problem. BTW, my test is performed under API 16.
Here is my demo: https://github.com/leoguo123/AndroidDemo
In the repository:
Test project contains 3 Activity(A > B > C) and it can show the Notification when receive a proper broadcast. SendBroadcast project is responsible for sending the broadcast.
The code for generating the notification:
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
showNotification(context);
}
private void showNotification(Context context) {
Intent intent = new Intent(context, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationManager nmr = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle("Open A with B and C being closed");
builder.setContentText("Open A with B and C being closed");
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentIntent(pi);
builder.setAutoCancel(true);
Notification nt = builder.build();
nmr.notify(0, nt);
}
}
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);