How do you build an Android back stack when an activity is started directly from a notification?
Asked Answered
F

4

24

I have two activities:

Activity A - list of items
Activity B - detail view of an item

Normally, a user opens the app and Activity A is launched. A user sees a list of items, clicks one, and Activity B is started to display the item detail.

Activity B can also be started directly from clicking on a notification. In this case there is no back stack.

How can I make it so that when Activity B is started directly from a notification, the user can click the Back button and go to Activity A?

Foliation answered 18/8, 2011 at 20:32 Comment(2)
I never being to this situation,so my answer might not be perfect. Instead of starting Activity B...Start Activity A and pass a value using Intent from your receiver and check for that value in onCreate of Activity A, if condition satisfies start Activity B. So through this you will have Activity A in backStack. But only catch is that user will see weird animation like Activity A coming and transitioning to Activity B. Does this make sense ?Sordino
@gopal yes I was considering implementing something like that. I will try it soon and report back.Foliation
S
23

You can add an Extra into the Intent launched by the notification to detect when the app has been launched in that way.

Then you can override the onBackPressed() Activity method and handle that scenario, e.g.

  @Override
  public void onBackPressed()
  {
    Bundle extras = getIntent().getExtras();

    boolean launchedFromNotif = false;

    if (extras.containsKey("EXTRA_LAUNCHED_BY_NOTIFICATION"))
    {
      launchedFromNotif = extras.getBoolean("EXTRA_LAUNCHED_BY_NOTIFICATION");
    }

    if (launchedFromNotif)
    {
      // Launched from notification, handle as special case
      Intent intent = new Intent(this, ActivityA.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
      mActivity.startActivity(intent);
      finish();
    }
    else
    {
      super.onBackPressed();
    }    
  }
Slam answered 25/10, 2011 at 18:40 Comment(3)
1up because this solution is api-level independent, contrary to the PendingIntent.getActivities() solution (https://mcmap.net/q/386468/-back-to-main-activity-from-notification-created-activity)Orchestrate
A check whether the extras bundle is not null is needed before accessing it.Intercede
@Orchestrate What do you mean by "PendingIntent.getActivities() is API-level dependent" ? As Cassio Landim points out, I'd recommend the "TaskStackBuilder" solution, editing the backStack, as advised by the guidelines.Vannessavanni
S
10

You should take care of this when you receive the Notification.

I have a similar situation solved:

 Intent intent = new Intent(context,ListDetail.class);
 TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
 stackBuilder.addParentStack(ListDetail.class);
 stackBuilder.addNextIntent(intent);
 PendingIntent contentIntent =
            stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
 NotificationManager mNotifM = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
 Notification.Builder mBuilder = new Notification.Builder(context);
 mNotifM.notify(NotificationId.getID(), mBuilder.setStyle(new Notification.BigTextStyle(mBuilder)
            .bigText(bigText)
            .setBigContentTitle(title)
            .setSummaryText(summaryText))
            .setContentTitle(title)
            .setSmallIcon(icon)
            .setContentText(summaryText)
            .setAutoCancel(true)
            .setContentIntent(contentIntent)
            .setTicker(bigText)
            .build());

You need to set in your Manifest the hierarchy of the Activities:

<activity
        android:name=".ListDetail"
        android:label="Detail"
        android:parentActivityName=".List" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".List" />
</activity>
Stewartstewed answered 1/5, 2015 at 16:47 Comment(0)
N
4

I have tried one sample.Please go through with this link

https://github.com/rajajawahar/NotificationBackStack

Activity you want to launch..

Intent launchIntent = new Intent(context, SecondActivity.class).putExtra("Id", id);

Parent Activity, if back pressed

Intent parentIntent = new Intent(context, FirstActivity.class);

Add Both the activity in the taskbuilder

TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); 
    PendingIntent resultPendingIntent = stackBuilder.addNextIntentWithParentStack(parentIntent).addNextIntent(launchIntent).getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder notificationCompatBuilder =
                new NotificationCompat.Builder(context);
        NotificationManager mNotificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(id, notificationCompatBuilder.build());
        NotificationManager mNotifyMgr =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationCompatBuilder.setAutoCancel(true).
                setContentTitle("First Notification").
                setContentText("Sample Text").
                setSmallIcon(R.mipmap.ic_launcher).
                setContentIntent(resultPendingIntent);
        mNotifyMgr.notify(id, notificationCompatBuilder.build());
Notwithstanding answered 5/10, 2016 at 10:20 Comment(0)
P
0

catch the back-button-key event with onKeyDown()-method and let the user go to activity A. Don't forget to return true to prevent the event from being propagated further.

http://developer.android.com/reference/android/app/Activity.html#onKeyDown(int, android.view.KeyEvent)

Pentad answered 22/8, 2011 at 23:45 Comment(2)
By "let the user go to Activity A", do you mean create an Intent and start Activity A? If I did that, and the user pushed the back button in Activity A, they would go back to Activity B, right?Foliation
yes, that's right. If you want to prevent this behaviour, try finishing your activity B after starting Activity A, i.e.: Intent i = new Intent(this, ActivityA.class); startActivity(i); finish();Pentad

© 2022 - 2024 — McMap. All rights reserved.