返回通知创建活动的主要活动

问题描述 投票:26回答:9

我正在尝试实现here描述的行为,其中通知(或其他)在您的应用程序中启动“内部”活动,然后当用户按下它时进入我的“主页”活动。

Android文档说

对于“后退”按钮,您应该通过在任务的后台堆栈中插入应用程序最顶层屏幕的完整向上导航路径,使导航更具可预测性。这允许忘记他们如何进入您的应用程序的用户在退出之前导航到应用程序的最顶层屏幕。

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

那么有一种非黑客的方法吗?

android
9个回答
68
投票

啊哈,我只需要使用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]

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


4
投票

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

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

注意,实际上不要在0中使用getPendingIntent作为requestCode。对我来说,任何数字都不是0,但是0导致后退按钮才进入启动器。


1
投票

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

  1. 从通知开始的活动中开始你的home activity。这可能会变得非常棘手,因为您必须区分并跟踪各种可能的切入点。
  2. 你总是从home activity开始检查是否通过通知启动,然后启动notification activity。这确保了一致的入口点,当用户按下向上键时后备栈将存在。

问候。


1
投票

此解决方案可以很好地解决此问题

android:noHistory="true"

0
投票

尼斯。

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

这对于构建一个从通知中访问活动的后台堆栈(通过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>

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

In addition to the above code also provide appropriate parent class names in your AndroidManifest.xml file.

0
投票

只需将此行添加到清单中即可。

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

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


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);
© www.soinside.com 2019 - 2024. All rights reserved.