NavUtils.shouldUpRecreateTask在JellyBean上失败了

14
我有一个应用程序发出通知,当选中时会启动一个活动。根据Android文档,我可以使用NavUtils.shouldUpRecreateTask来检查活动是否已直接启动(即从通知中)或通过常规活动堆栈启动。但它给出了错误的答案。我在JellyBean上进行测试,但使用支持库。
基本上,shouldUpRecreateTask始终返回false,即使该活动是从通知中启动的。
对于为什么shouldUpRecreateTask无法给出正确答案,您有任何想法吗?

嗨 Clyde,shouldUpRecreateTask 在 jellybean 之前对你有用吗?我总是在模拟器上得到 false,无论我是否在打开通知之前杀死了我的应用程序。 - Maragues
我其实也遇到了完全相同的问题。据我所知,它似乎是有问题的。 - Pork 'n' Bunny
请参见https://dev59.com/amUq5IYBdhLWcg3wT-yD。 - riwnodennyk
3个回答

7

这不是正确的做法!当你从通知开始时,必须根据此处所述创建堆栈: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse

因此,在创建通知时,您需要执行以下操作:

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);

当您单击UP(上)按钮时,需要使用常规代码,即:

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);
}

这对我来说完美运作。

+1,这似乎是我认为最好/最正确的答案。谢谢。 - akent
1
TaskStackBuilder.getPendingIntent将FLAG_ACTIVITY_CLEAR_TASK标志设置到意图中,这会导致在2.3以上版本中onNewIntent()不会按预期调用。因此,在我看来,最好放弃TaskStackBuilder,改用普通的PendingIntent。 - jiashie
链接更新:目前,有关构建通知堆栈的文档可以在此处找到:https://developer.android.com/training/notify-user/navigation(滚动到“使用返回堆栈构建PendingIntent”)。 - Peter

5
我仍然不知道为什么shouldUpRecreateTask失败了——查看它的源代码并没有什么帮助。但解决方案非常简单——我只需要在附加到通知的Intent中添加一个额外的标志值,并在onCreate()中检查它。如果设置了该标志,则Activity已从通知中调用,因此必须重新创建后退堆栈。
代码如下:
@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;
}

1
这并没有帮助,如果我们已经在使用该应用程序,则会破坏真正的返回堆栈。如果我们的应用程序已关闭,则可以。 - Maragues
如果活动已经打开,则不会调用onCreate,而是调用onNewIntent,因此fromNotification未设置,因此后退堆栈保持不变。如果活动未打开,则销毁现有的后退堆栈正是我想要的。 - Clyde
为什么要使用 getInt("fromNotification") == 1,如果你可以使用类似 getBoolean("fromNotification", false) 的东西呢? - ademar111190
@ademar111190 没有特别的原因。 - Clyde

4

我和OP遇到了同样的问题。NavUtils.shouldUpRecreateTask似乎总是返回false。(在JellyBean上也是如此) 我使用了以下方法来实现相同的功能。

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;

“parent”意图可以通过以下方式获取,而不是硬编码。
Intent upIntent = NavUtils.getParentActivityIntent(this);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接