Back to main activity from notification-created activity
Asked Answered
L

10

41

I'm trying to implement the behaviour described here, where a notification (or whatever) starts an "internal" activity in your app, and then when the user pressed back it goes to my "home" activity.

The Android docs say

In the case of the Back button, you should make navigation more predictable by inserting into the task's back stack the complete upward navigation path to the app's topmost screen. This allows users who've forgotten how they entered your app to navigate to the app's topmost screen before exiting.

Is there a good way to actually do that? Other questions on Stackoverflow suggest starting the main activity with an intent that tells it to start the internal activity, but that seems like a huge hack, that I somewhat doubt Google would have used in Gmail, and I assume there is a decent method, given that they are advocating the behaviour.

So is there a non-hacky way to do this?

Lectra answered 10/12, 2012 at 12:10 Comment(0)
L
82

Aha, I simply need to use PendingIntent.getActivities() instead of getActivity(). Also worth mentioning is TaskStackBuilder

Here is some code:

    Intent backIntent = new Intent(ctx, MainActivity.class);
    backIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    Intent intent = new Intent(ctx, ConversationActivity.class);
    intent.putExtra("whatever", whatever);
    final PendingIntent pendingIntent = PendingIntent.getActivities(ctx, UNIQUE_REQUEST_CODE++,
            new Intent[] {backIntent, intent}, PendingIntent.FLAG_ONE_SHOT);

Just tested it. It works like a charm. I initially suspected that there might be a problem if the app is already running, and you go to a notification. I.e. say you activity stack is (topmost on the right):

[MainActivity] [SomeActivity]

and you click a notification for ConversationActivity. Would you get:?

[MainActivity] [SomeActivity] [MainActivity] [ConversationActivity]

Well, it turns out you magically get

[MainActivity] [SomeActivity] [ConversationActivity]

which is what I wanted, but I have no idea how it does that. I haven't set any special options on any of the activities. Oh well!

Lectra answered 10/12, 2012 at 12:42 Comment(4)
Sadly, this doesn't appear to work for me. My MainActivity indeed gets pushed onto the navigation stack again, and it only works one time for one notification (I don't auto-dismiss them). Any ideas?Disarmament
@bompf, that's probably because of PendingIntent.FLAG_ONE_SHOT being used in PendingIntent.getActivities. I suggest PendingIntent.FLAG_CANCEL_CURRENT instead.Brownley
Thanks; this worked for me, whereas TaskStackBuilder didn't seem to work. However, your code resulted in a weird condition: if I opened MainActivity via the launcher and then opened the action from the notification, after pressing the back button to go back to MainActivity, pressing the back button resulted in it going to MainActivity again. Like this: [MainActivity] [MainActivity] [ConversationActivity]. I fixed it by changing your second line of code to backIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK).Brownley
Awesome! TaskStackBuilder wasn't working for me (developer.android.com/guide/topics/ui/notifiers/…), but well lazy is lazy...Riobard
B
9

There is a new guide on how to do this, and it suggest some slightly different practices than the answers above:

https://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse

Note, don't actually use 0 for your requestCode in getPendingIntent. For me any number not 0 worked, but 0 resulted in the back button just going to the launcher.

Balsaminaceous answered 19/7, 2017 at 4:34 Comment(3)
this is the only solution that really worked for me, thank you sir!Freedafreedman
This was really helpful. Following the instructions from the Android documentation without changing requestCode did not workLaubin
Great work, But what if I want to back with a button. What Should I use!Horwath
D
4

I know 2 ways of achieving this:

  1. Start your home activity from within activity started by notification. This may become quite trick, as you will have to differentiate and keep track of various possible entry points.
  2. You always start with you home activity which checks if is being started by a notification and then starts the notification activity. This ensures a consistent entry point and the back stack will be there when user press Up key.

Regards.

Dill answered 10/12, 2012 at 12:34 Comment(0)
C
2
Intent displayIntent = new Intent(getApplicationContext(), TargetActivity.class);

displayIntent.putExtra("extra_id", "extra_key");

TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext());
stackBuilder.addParentStack(TargetActivity.class);
stackBuilder.addNextIntent(displayIntent);
stackBuilder.editIntentAt(1).putExtra("extra_id", "extra_key");

PendingIntent contentIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
        getApplicationContext(), "123").setSmallIcon(R.drawable.logo)
        .setContentTitle("GCM Notification")
        .setStyle(new NotificationCompat.BigTextStyle().bigText("Sample")).setContentText("sample text");

mBuilder.setContentIntent(contentIntent);

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(456, mBuilder.build());
stackBuilder.startActivities();

In addition to the above code also provide appropriate parent class names in your AndroidManifest.xml file.

Caisson answered 21/11, 2018 at 8:46 Comment(0)
I
0

Nice.

But be aware that is does not work on pre-3.0 (pre API level 11) system because PendingIntent.getActivities() is not available there.

And that is the same for constructing a backstack to access an activity from a notification (via Intent) and have the back button behaves coherently with your application (detail activity comes back to list activity for example).

Inversion answered 10/1, 2014 at 18:18 Comment(0)
E
0

Activities are associated with a task which is nothing but a group of activities in the back stack. When you open up a new activity upon click of the notification, that activity is opened as an independent activity and is put into a new task. This means only the notification activity and the parent activity are present.

Just specify the launch mode of your activity as "standard" in the manifest file and it should resolve the issue.

Intent resultIntent = new Intent(getApplicationContext(),
                        ResultActivity.class);

PendingIntent resultPendingIntent =
    PendingIntent.getActivity(getApplicationContext(),0,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);

mBuilder.setContentIntent(resultPendingIntent); 

NotificationManager mNotificationManager = (NotificationManager)
    getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(notId, mBuilder.build());

manifest:

<activity
            android:name="com.mns.exercisenotifications.ResultActivity"
            android:label="@string/app_name"
            android:launchMode="standard" >  <---
            <intent-filter>
                <action android:name="com.mns.exercisenotifications.ResultActivity" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

 </activity>
Especially answered 3/7, 2014 at 9:44 Comment(0)
C
0

This solution works great exactly for this problem

android:noHistory="true"
Coon answered 26/1, 2017 at 7:33 Comment(1)
where to add this?Hewie
W
0

just add this lines to your manifest.

<activity
    android:name=".YourActivity"
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>

for a complete guideline refer to https://developer.android.com/training/notify-user/navigation

Warrantee answered 20/3, 2019 at 20:3 Comment(1)
I'm pretty sure singleTask doesn't prevent multiple instances of an activity in the same task.Lectra
F
0

I know I'm late but this may help someone.
Just create an intent for the activity you want to open with the notification. Then set Intent.FLAG_ACTIVITY_NEW_TASK and Intent.FLAG_ACTIVITY_CLEAR_TASK as flags.
Then all you need to do is to create a PendingIntent with your intent as parameter.

This is a code example:

Intent intent = new Intent(this, NotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
Floodlight answered 27/3, 2019 at 5:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.