Android文档说:
在Back按钮的情况下,您应该通过将完整的向上导航路径插入到任务的返回堆栈中来使导航更加可预测。这允许忘记如何进入您的应用程序的用户在退出之前导航到应用程序的最高屏幕。
有没有好的方法来实现这一点?Stackoverflow上的其他问题建议使用一个意图来启动内部活动并告诉它启动主要活动,但这似乎是一个巨大的hack,我有些怀疑Google会在Gmail中使用它,并且我假设有一个像样的方法,因为他们提倡这种行为。
那么有没有不需要hack的方法来实现这个目标呢?
啊哈,我只需要使用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]
这正是我想要的,但我不知道它是如何做到的。我没有在任何活动中设置任何特殊选项。哦,算了吧!
有一份新的指南教你如何做到这一点,它提出了一些与上面的答案略有不同的实践建议:
https://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse
注意,不要在getPendingIntent
中实际使用0
作为您的requestCode。对我来说,任何非0的数字都可以工作,但是0会导致返回按钮直接回到启动器。主页活动
。这可能会变得非常棘手,因为您将不得不区分和跟踪各种可能的入口点。主页活动
开始,检查是否正在通过通知启动,然后启动通知活动
。这确保了一致的入口点,并且当用户按上键时,返回堆栈将在那里。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
文件中提供适当的父类名称。
只需将这些行添加到您的清单中。
<activity
android:name=".YourActivity"
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>
如需完整指南,请参阅https://developer.android.com/training/notify-user/navigation
singleTask
不能防止在同一个任务中出现多个活动实例。 - TimmmmIntent.FLAG_ACTIVITY_NEW_TASK
和Intent.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);
活动与任务相关联,任务只是后台堆栈中的一组活动。当您在通知上单击打开新活动时,该活动将作为独立活动打开并放入新任务中。这意味着只有通知活动和父活动存在。
只需在清单文件中将您的活动启动模式指定为“标准”,即可解决此问题。
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>
不错。
但请注意,它在3.0之前(API级别11之前)的系统上无法使用,因为PendingIntent.getActivities()在那里不可用。
对于通过Intent从通知访问活动并使返回按钮与您的应用程序协同一致(例如,详细活动返回到列表活动),构建后堆栈也是如此。
这个解决方案非常适用于这个问题
android:noHistory="true"
PendingIntent.getActivities
中使用了PendingIntent.FLAG_ONE_SHOT
。我建议改用PendingIntent.FLAG_CANCEL_CURRENT
。 - SamTaskStackBuilder
对我不起作用(https://developer.android.com/guide/topics/ui/notifiers/notifications.html),但是懒惰就是懒惰... - xyz