意图 - 如果活动正在运行,请将其置于最前面,否则启动一个新的(来自通知)

urS*_*Sus 122 android android-intent android-activity android-pendingintent

我的应用程序有通知,这是 - 很明显 - 没有任何标志,每次启动一个新的活动,所以我得到对方的顶部,这是错误的运行多个同样的活动.

我想要它做的是将通知挂起意图中指定的活动带到前面(如果它已在运行),否则启动它.

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

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);
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,它有时会起作用,有时它不会......我觉得我已经尝试了每一个标志组合.

Fra*_*nco 124

你可以用这个:

<activity 
   android:name=".YourActivity"
   android:launchMode="singleTask"/>
Run Code Online (Sandbox Code Playgroud)

这将工作类似"singleInstance"但它不会有那个奇怪的动画.

  • +1,你应该是接受的答案.差异在这里:http://developer.android.com/guide/topics/manifest/activity-element.html#lmode (15认同)
  • 如果像我这样的人在他们最终在这个网站上尝试了许多解决方案的组合:确保摆脱你尝试过的其他变化,并确保你对正确的活动做了这个改变.我花了太长时间才发现如果我没有尝试过其他解决方案(例如重写`onNewIntent`和设置标志),这个解决方案就会有效 (4认同)

Mar*_*res 42

我认为以最简单的方式执行此操作的最佳方法是正常启动活动,但使用singleInstance属性在清单中设置该活动.通过这种方式,您实际上可以通过将活动始终放在前面来解决您现在遇到的两个问题,并且如果没有活动则让操作系统自动创建一个新的活动,或者将当前存在的活动带到前面(感谢singleInstance属性).

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

<activity 
   android:name=".YourActivity"
   android:launchMode="singleInstance"/>
Run Code Online (Sandbox Code Playgroud)

另外为了避免在通过singleInstance启动时出现波动的动画,你可以使用"singleTask",两者都非常相似,但这里的差异按照Google的文档解释:

<activity 
   android:name=".YourActivity"
   android:launchMode="singleTask"/>
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助.

问候!

  • 它似乎工作,但现在我从singleIntent MainActivity启动的所有其他新活动,播放这个奇怪的电弧动画而不是常规的淡入淡出和缩放 (4认同)

Shl*_*blu 25

我认为你需要的是singleTop Activity,而不是一个singleTasksingleInstance.

<activity android:name=".MyActivity"
          android:launchMode="singleTop"
          ...the rest... >
Run Code Online (Sandbox Code Playgroud)

什么文件说,不完全满足您的需求:

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

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

  • 周五晚上工作到晚上 10 点,这就是我想要的……可悲的开发者生活。 (3认同)

And*_*kyy 8

这是旧线程,但是对于所有仍在寻找答案的人,这是我的解决方案。它完全是代码,没有清单设置:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 与这些标志战斗了几个小时,并想知道为什么改变我的意图标志没有改变任何东西。非零请求代码...需要提及的至关重要的一点!现在可以工作了!谢谢你! (5认同)

Raz*_*a O 6

我知道它很旧,但是以上内容都不适合我的应用程序。

在不更改清单和其他配置的情况下,以下代码可将您的应用重新带到前面-或在关闭时将其打开

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);
Run Code Online (Sandbox Code Playgroud)

  • 不,这是行不通的-它会在当前活动的顶部添加一个新活动。 (2认同)