Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NavUtils.shouldUpRecreateTask fails on JellyBean

I have an application that issues notifications that when selected start an activity. According to the Android docs I can use NavUtils.shouldUpRecreateTask to check whether the activity has been started directly (i.e. from the notification) or via a normal activity stack. However it gives the wrong answer. I'm testing this on JellyBean but using the support library.

Basically shouldUpRecreateTask always returns false, even when the activity has been started form the notification.

Any ideas on why shouldUpRecreateTask is failing to give the correct answer?

like image 639
Clyde Avatar asked Dec 30 '12 10:12

Clyde


3 Answers

This is not correct! When you start from the notification you have to create the stack when building the notification as explained here: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse

Therefore when creating the notification you'll have to do this:

Intent resultIntent = new Intent(this, ResultActivity.class);
// ResultActivity is the activity you'll land on, of course
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
// make sure that in the manifest ResultActivity has parent specified!!!
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

and then when you click on the UP button you need the regular code, which is:

if (NavUtils.shouldUpRecreateTask(this, intent)) {
    // This activity is NOT part of this app's task, so
    // create a new task when navigating up, with a
    // synthesized back stack.
    TaskStackBuilder.create(this)
    // Add all of this activity's parents to the back stack
            .addNextIntentWithParentStack(intent)
            // Navigate up to the closest parent
            .startActivities();
} else {
    NavUtils.navigateUpTo(this, intent);
}

This works perfectly for me.

like image 74
Ciprian Avatar answered Nov 03 '22 00:11

Ciprian


I still don't know why shouldUpRecreateTask fails - looking at the source code for it doesn't help much. But the solution is quite simple - I just add an extra flag value to the Intent that is attached to the notification, and check this in onCreate(). If it is set, then the Activity has been invoked from the notification, so the back stack has to be recreated.

The code looks like this:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle b = getIntent().getExtras();
    fromNotification = b.getInt("fromNotification") == 1;
    setContentView(R.layout.threadlist);
}

@Override
public boolean onHomeButtonPressed() {
    if(fromNotification) {
        // This activity is not part of the application's task, so create a new task
        // with a synthesized back stack.
        TaskStackBuilder tsb = TaskStackBuilder.from(this)
                .addNextIntent(new Intent(this, COPAme.class));
        tsb.startActivities();
    } 
        // Otherwise, This activity is part of the application's task, so simply
        // navigate up to the hierarchical parent activity.
    finish();
    return true;
}
like image 42
Clyde Avatar answered Nov 03 '22 01:11

Clyde


I had the same problem as OP. NavUtils.shouldUpRecreateTask always seemed to return false. (JellyBean also) I used the following the achieve the same functionality.

case android.R.id.home:
Intent upIntent = new Intent(this,ParentActivity.class);
upIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(upIntent);
finish();
return true;

The 'parent' intent could be fetched this way instead of hard coding.

Intent upIntent = NavUtils.getParentActivityIntent(this);
like image 4
David Avatar answered Nov 03 '22 01:11

David