Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TaskStackBuilder and extras for the back stack

Tags:

android

I'm trying to use TaskStackBuilder with notifications to create a back stack for the back button to go through. Normal flow of my app:

  1. Activity A is launched from the launcher.
  2. User selects an item from A, which launches B with extras for what to load.
  3. User selects an item from B, this launches C with extras for what to load.

Sometimes, after a background update when the user isn't using my app, I generate a notification. If they click this notification, it launches Activity C, skipping A and B. I'm trying to follow the design guidelines and create a back stack, so when they press back it will go to Activity B instead of the home screen. My problem is that Activity B requires an extra in its launch intent to tell it what to grab from the database.

My current TaskStackBuilder code:

TaskStackBuilder sBuilder = TaskStackBuilder.create( this );
sBuilder.addParentStack( ActivityC.class );
sBuilder.addNextIntent( launchIntent );

pIntent = sBuilder.getPendingIntent( 0, PendingIntent.FLAG_ONE_SHOT );

Clicking on the notification launches Activity C just fine, but when I press back it explodes with an IllegalArgumentException from my ContentProvider because Activity B doesn't know what ID to request. Is there any way to get this extra into the back stack or am I stuck?

like image 250
Ralgha Avatar asked Oct 30 '12 22:10

Ralgha


3 Answers

This line:

sBuilder.addParentStack( ActivityC.class );

adds all parents declared for ActivityC in AndroidManifest.xml in <meta-data>. I don't know what it is, I haven't used it. I doubt you need it.

This line adds intent to an array:

sBuilder.addNextIntent(launchIntent);

then the array of intents is used to create PendingIntent, probably with PendingIntent.getActivities, I couldn't find the implementation, which is then started somewhere with Context.startActivities.

I think you just need to create set of intents, there you can add extras:

Intent activityA = new Intent(context, ActivityA.class);
activityA.putExtra(key, valueA);
Intent activityB = new Intent(context, ActivityB.class);
activityB.putExtra(key, valueB);
Intent activityC = new Intent(context, ActivityC.class);
activityC.putExtra(key, valueC);

and add them to builder:

sBuilder.addNextIntent(activityA);
sBuilder.addNextIntent(activityB);
sBuilder.addNextIntent(activityC);
pIntent = sBuilder.getPendingIntent( 0, PendingIntent.FLAG_ONE_SHOT );

I haven't tested it, this is only a result of my fast research, I hope someone will correct me if I'm wrong.

like image 155
pawelzieba Avatar answered Nov 11 '22 17:11

pawelzieba


I found another way to tackle this problem: use the method TaskStackBuilder.editIntentAt(int)

ex.

Intent intentC = new Intent(context, ActivityC.class);
intentC.putExtra(key, valueC);

TaskStackBuilder sBuilder = TaskStackBuilder.create(this)
    .addParentStack(ActivityB.class)
    .addParentStack(ActivityC.class)
    .addNextIntent(intentC);

Intent intentA = sBuilder.editIntentAt(0);
intentA.putExtra(key, value);
Intent intentB = sBuilder.editIntentAt(1);
intentB.putExtra(key, value);
like image 21
Daniel Jette Avatar answered Nov 11 '22 15:11

Daniel Jette


I have struggled with this one. My research resulted in the following solution (very similar to @pawelzieba but with one important deletion):

Intent activityA = new Intent(context, ActivityA.class);
activityA.putExtra(key, valueA);
Intent activityB = new Intent(context, ActivityB.class);
activityB.putExtra(key, valueB);
Intent activityC = new Intent(context, ActivityC.class);
activityC.putExtra(key, valueC);

TaskStackBuilder sBuilder = TaskStackBuilder.create(this)
    .addNextIntent(activityA);
    .addNextIntent(activityB);
    .addNextIntent(activityC);
PendingIntent pIntent = sBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT );

Note that you should not modify your manifest with the parent associations, and you do not want to use:

sBuilder.addParentStack( ActivityC.class );

or else you will get repeats of ActivityA and ActivityB in the newly created task that have intents without extras. If you do not need to pass intents with extras, you could add the parent associations in the manifest and call addParentStack().

like image 9
pigswig Avatar answered Nov 11 '22 17:11

pigswig