40

我正在尝试实现此处描述的行为,其中通知(或其他)在您的应用程序中启动“内部”活动,然后当用户按下它时,它会转到我的“家庭”活动。

Android 文档说

在返回按钮的情况下,您应该通过将完整的向上导航路径插入到任务的返回堆栈中来使导航更可预测到应用程序的最顶层屏幕。这允许忘记如何进入您的应用程序的用户在退出之前导航到应用程序的最顶部屏幕。

有没有真正做到这一点的好方法?Stackoverflow 上的其他问题建议以告诉它开始内部活动的意图来启动主要活动,但这似乎是一个巨大的黑客攻击,我有点怀疑谷歌会在 Gmail 中使用它,我认为有一个不错的方法,给定他们提倡这种行为。

那么有没有一种非hacky的方法来做到这一点?

4

10 回答 10

81

啊哈,我只需要使用PendingIntent.getActivities()而不是getActivity(). 另外值得一提的是TaskStackBuilder

这是一些代码:

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

刚刚测试过了。它就像一个魅力。我最初怀疑如果应用程序已经在运行,可能会出现问题,然后你去通知。即说你的活动堆栈是(最右边):

[MainActivity] [SomeActivity]

然后单击 的通知ConversationActivity。你会得到:?

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

好吧,事实证明你神奇地得到了

[MainActivity] [SomeActivity] [ConversationActivity]

这就是我想要的,但我不知道它是如何做到的。我没有对任何活动设置任何特殊选项。那好吧!

于 2012-12-10T12:42:00.207 回答
8

有一个关于如何做到这一点的新指南,它提出了一些与上述答案略有不同的做法:

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

请注意,实际上不要将0您的 requestCode 用于getPendingIntent. 对我来说,任何不是 0 的数字都有效,但 0 导致后退按钮只是转到启动器。

于 2017-07-19T04:34:12.470 回答
4

我知道实现这一目标的两种方法:

  1. 从通知开始home activity的活动开始。这可能会变得很棘手,因为您必须区分并跟踪各种可能的入口点。
  2. 你总是从你开始,home activity它检查是否由通知启动,然后启动notification activity. 这确保了一致的入口点,并且当用户按下 Up 键时,返回堆栈将在那里。

问候。

于 2012-12-10T12:34:40.317 回答
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();

除了上述代码之外,还要在您的AndroidManifest.xml文件中提供适当的父类名称。

于 2018-11-21T08:46:43.133 回答
1

这个解决方案非常适合这个问题

android:noHistory="true"
于 2017-01-26T07:33:25.220 回答
0

好的。

但请注意,这在 3.0 之前(API 级别 11 之前)系统上不起作用,因为 PendingIntent.getActivities() 在那里不可用。

这与构造一个 backstack 以从通知(通过 Intent)访问活动并让后退按钮与您的应用程序一致(例如,详细活动返回到列表活动)是相同的。

于 2014-01-10T18:18:34.870 回答
0

活动与一个任务相关联,该任务不过是后台堆栈中的一组活动。当您在单击通知时打开新活动时,该活动将作为独立活动打开并放入新任务中。这意味着只有通知活动和父活动存在。

只需在清单文件中将您的活动的启动模式指定为“标准”,它应该可以解决问题。

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

显现:

<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>
于 2014-07-03T09:44:28.343 回答
0

我知道我迟到了,但这可能会对某人有所帮助。
只需为要使用通知打开的活动创建一个意图。然后设置Intent.FLAG_ACTIVITY_NEW_TASKIntent.FLAG_ACTIVITY_CLEAR_TASK作为标志。
然后您需要做的就是以PendingIntent您的意图作为参数创建一个。

这是一个代码示例:

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);
于 2019-03-27T05:58:36.530 回答
0

只需将此行添加到您的清单中。

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

有关完整指南,请参阅https://developer.android.com/training/notify-user/navigation

于 2019-03-20T20:03:40.220 回答