Android 通知单击保持堆栈并在需要时将应用程序置于最前面。如果特定活动在顶部,则传递数据
Posted
技术标签:
【中文标题】Android 通知单击保持堆栈并在需要时将应用程序置于最前面。如果特定活动在顶部,则传递数据【英文标题】:Android Notification click keep stack and bring app to front if need. Pass data if specific activity is on top 【发布时间】:2020-10-09 14:17:14 【问题描述】:如何单击通知,在需要时将我的应用程序置于前台,并保持堆栈不变(即使应用程序进入后台)?
我有一个NotificationClickActivity
,当用户单击通知时会启动它。
点击通知时,我有两种可能的情况:
-
用户已从应用程序中注销
用户已登录。
在第一个场景中,NotificationClickActivity
启动登录过程并接收结果。如果OK,我启动MainActivity
。任务被清除,所以MainActivity
是我在任务中的唯一活动。在这种情况下我没有问题。
在第二种情况下NotificationClickActivity
这样做:
finish()
startActivity(MainActivity.createIntent(this).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP).putExtra("notification", notification))
使用上面的代码,如果应用程序已经在运行(MainActivity
是根和***活动)并且在后台或前台,我没有问题。 MainActivity
onNewIntent
被调用,我可以对通知做任何事情。在这种情况下,我将通知发送到存储库。
我面临的问题是当我在MainActivity
之上进行活动时。想象一下下面的堆栈:
MainActivity -> ActivityOne -> ActivityTwo -> ActivityN
如果我单击通知,堆栈变为:
MainActivity -> ActivityOne -> ActivityTwo -> ActivityN -> MainActivity
我希望堆栈保持MainActivity -> ActivityOne -> ActivityTwo -> ActivityN
,但仍将通知传递给MainActivity
,以便可以将其分派到存储库。
知道如何实现这一目标吗?
我一直在使用意图标志,但没有成功。 当然,我没有任何可见的动画或其他任何东西,这样用户就不会意识到发生了什么。
【问题讨论】:
【参考方案1】:认为您正在寻找FLAG_ACTIVITY_REORDER_TO_FRONT
.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP || FLAG_ACTIVITY_REORDER_TO_FRONT)
如果 Activity 已经在运行,这会将其带到栈顶。
考虑一个由四个活动组成的任务:A、B、C、D。如果 D 调用 startActivity() 的 Intent 解析为活动 B 的组件,则 B 将被带到历史堆栈的前面,结果顺序为:A、C、D、B。
在上面的示例中,如果您想从 A,B,C,D 转到 A,B,C,D,B,则需要确保您的 Activity 支持多个实例。
建议 FLAG_ACTIVITY_SINGLE_TOP
改为在 android 清单中为活动指定。然后在您的onNewIntent
中检查用户是否已登录。如果用户未登录,则应使用startActivityForResult
启动登录过程并使用onActivityResult
处理登录结果。
这假设您的登录可以通过 Intent 启动,该 Intent 调用 setResult
并提供足够的信息供调用者确定登录是否成功。
至于动画,我认为您将不得不使用片段并禁用动画,或者禁用 Activity 的动画,并且仅在需要时进行自定义转换。这甚至可能不适用于 Activity,因为无论如何,操作系统/OEM 定义的转换可能只会发生在 Activity 中,因此您很可能必须确保应用程序的其余部分在同一个 Activity 中并使用片段进行导航。
【讨论】:
谢谢,但我不想重新排序到前面。此外,当我的用户注销时,我没有任何问题。我只有当他登录并且堆栈是 A、B、C、D 时才有。在这种情况下,单击通知我想将堆栈保持为 A、B、C、D 但是: 1 - 将信息传递给 A和 2 - 如果应用程序在后台,则将其置于前台。另一种可能性是检查最重要的活动是什么。 对。简短的回答是否定的。将信息传递给活动的唯一方法是将其从暂停状态中恢复,这意味着它开始并来到前面。我相信你想要的是更新一些状态,A 可以在下一次“恢复”时刷新。为此,您可以使用没有任何 UI 的单独活动来处理意图和完成。根据将当前活动放在前面,您可能可以使您的意图更通用。设置类别和包名称,但不指定活动。认为这就是单击启动器图标时发生的情况。这可能行得通。【参考方案2】:使用这种方法是不可能的。如果当前任务包含MainActivity
以及除此之外的其他活动,则无法使用startActivity
或启动Activity
。
如果您需要向MainActivity
获取信息,那么您需要使用另一种机制来执行此操作:
Intent
并让 MainActivity
收听广播
使用事件总线实现
使用“全局变量”在 2 个活动之间传递此信息
【讨论】:
以上是关于Android 通知单击保持堆栈并在需要时将应用程序置于最前面。如果特定活动在顶部,则传递数据的主要内容,如果未能解决你的问题,请参考以下文章
Android - 点击时 Firebase 通知会打开一个 Activity
Android 应用程序未在 Com.onesignal 通知中启动单击