138

我的应用程序有通知,显然 - 没有任何标志,每次都启动一个新活动,所以我得到多个相同的活动在彼此之上运行,这是错误的。

我想要它做的是将通知待处理意图中指定的活动带到前面,如果它已经在运行,否则启动它。

到目前为止,我拥有的该通知的意图/待定意图是

private static PendingIntent prepareIntent(Context context) {
    Intent intent = new Intent(context, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

    return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

奇怪的是,它有时有效,有时无效……我觉得我已经尝试过每一种标志组合。

4

8 回答 8

136

你可以使用这个:

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

这将类似于"singleInstance"但它不会有那个奇怪的动画。

于 2014-04-17T05:57:41.647 回答
47

我认为以简单的方式执行此操作的最佳方法是正常启动活动,但使用singleInstance属性在清单中设置该活动。有了这个,您实际上可以解决您现在遇到的两个问题,方法是始终将活动置于最前面,并让操作系统在不存在活动时自动创建一个新活动,或者将当前存在的活动置于最前面(感谢singleInstance财产)。

这是将活动声明为单个实例的方式:

<activity 
   android:name=".YourActivity"
   android:launchMode="singleInstance"/>

此外,为了避免通过 singleInstance 启动时出现断断续续的动画,您可以改用“singleTask”,两者非常相似,但根据 Google 的文档在此处解释了不同之处:

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

singleInstance 与“singleTask”相同,只是系统不会在持有该实例的任务中启动任何其他活动。活动始终是其任务的唯一且唯一的成员。

希望这可以帮助。

问候!

于 2013-09-26T21:45:57.763 回答
26

我认为您需要的是 in singleTop Activity,而不是singleTaskor singleInstance

<activity android:name=".MyActivity"
          android:launchMode="singleTop"
          ...the rest... >

文档所说的完全适合您的需求:

singleTop[...]还可以创建" " 活动的新实例来处理新意图。但是,如果目标任务在其堆栈顶部已经有活动的现有实例,则该实例将接收新意图(在onNewIntent()调用中);未创建新实例。在其他情况下——例如,如果“ singleTop”活动的现有实例在目标任务中,但不在堆栈的顶部,或者如果它在堆栈的顶部,但不在目标任务中 - 一个新的实例将被创建并推送到堆栈上。

最重要的是(没有双关语),我和你有完全相同的需求。我测试了所有launchMode标志,以了解它们在实践中的实际行为,因此singleTop实际上是最好的:没有奇怪的动画,应用程序在最近的应用程序列表中显示一次(不像singleInstance它显示两次,因为它没有t 允许任何其他Activity人成为其任务的一部分),并且无论目标是否Activity已经存在,都应采取适当的行为。

于 2016-03-22T09:06:34.147 回答
18

这是旧线程,但对于所有仍在寻求答案的人来说,这是我的解决方案。它纯粹是在代码中,没有清单设置:

private static PendingIntent prepareIntent(Context context) {
  Intent intent = new Intent(context, MainActivity.class);
  intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);      
  return PendingIntent.getActivity(context, NON_ZERO_REQUEST_CODE, intent, 
    PendingIntent.FLAG_UPDATE_CURRENT);
}

如果 FLAG_ACTIVITY_SINGLE_TOP 位于任务堆栈的顶部,则在此处打开现有活动。如果它不在顶部,而是在堆栈内部,FLAG_ACTIVITY_CLEAR_TOP 将删除目标活动顶部的所有活动并显示它。如果 Activity 不在任务堆栈中,则将创建新的。需要提到的一个至关重要的点 - PendingIntent.getActivity() 的第二个参数,即 requestCode 应该具有非零值(我什至在我的代码段中将其称为 NON_ZERO_REQUEST_CODE),否则这些意图标志将不起作用。我不知道为什么会这样。标志 FLAG_ACTIVITY_SINGLE_TOP 可与清单中活动标记中的 android:launchMode="singleTop" 互换。

于 2019-01-10T14:55:22.867 回答
10

我知道它已经过时了,但上面的任何内容都不适合我的应用程序。

在不更改清单和其他配置的情况下,这里是让您的应用程序回到前面的代码 - 或者在关闭时打开它

Intent notificationIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
notificationIntent.setPackage(null); // The golden row !!!
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
于 2017-11-16T12:30:47.513 回答
3

我试过了,即使 IDE 抱怨代码,它也能正常工作

Intent notificationIntent = new Intent(THIS_CONTEXT, MainActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    PendingIntent intent = PendingIntent.getActivity(THIS_CONTEXT, 0, notificationIntent, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(THIS_CONTEXT)
            .setSmallIcon(R.drawable.cast_ic_notification_0)
            .setContentTitle("Title")
            .setContentText("Content")
            .setContentIntent(intent)
            .setPriority(PRIORITY_HIGH) //private static final PRIORITY_HIGH = 5;
            .setAutoCancel(true)
            /*.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)*/;
    NotificationManager mNotificationManager = (NotificationManager) THIS_CONTEXT.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(0, mBuilder.build());
于 2016-11-10T12:43:17.227 回答
2

既然你说你想开始你的活动,如果它还没有开始,也许你不介意重新启动它。我还针对意图测试了大量建议和标志组合,这将始终将您需要的活动带到最前面,尽管它不会保留以前与之关联的任何状态。

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);

仅限 API11+。

于 2015-11-29T21:39:42.613 回答
1

添加通知后,我遇到了类似的问题,如在android 培训网站上发现的那样。这里没有其他答案对我有用,但是这个答案对我有用。概括:

final Intent notificationIntent = new Intent(context, YourActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
于 2019-04-23T22:27:42.273 回答