java 从通知中恢复活动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2386542/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
resuming an activity from a notification
提问by mazbox
I have a notification in the status bar for my app:
我的应用程序的状态栏中有一条通知:
Notification notification = new Notification(R.drawable.icon, null, System.currentTimeMillis());
Intent notificationIntent = new Intent(this.parent, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this.parent, 0, notificationIntent, 0);
...
notification.flags = Notification.FLAG_ONGOING_EVENT;
mNotificationManager.notify(NOTIFICATION_ID, notification);
The problem with this is that when you press the home button from the app (pushing it to the background) then press on the notification in the list accessed from the status bar, it starts a fresh copy of the activity. All I want to do is resume the app (like when you longpress the home button and press on the app's icon). Is there a way of creating an Intent to do this?
问题在于,当您按下应用程序中的主页按钮(将其推到后台)然后按下从状态栏访问的列表中的通知时,它会启动该活动的新副本。我想要做的就是恢复应用程序(比如当你长按主页按钮并按下应用程序的图标时)。有没有办法创建一个意图来做到这一点?
采纳答案by rekaszeru
I've solved this issue by changing the launchModeof my activity to singleTaskin the androidManifest.xml file.
我已经改变了解决这个问题launchMode我的活动,以singleTask在AndroidManifest.xml文件。
The default value for this property is standard, which allows any number of instances to run.
此属性的默认值为standard,它允许运行任意数量的实例。
"singleTask" and "singleInstance" activities can only begin a task. They are always at the root of the activity stack. Moreover, the device can hold only one instance of the activity at a time — only one such task. [...]
The "singleTask" and "singleInstance" modes also differ from each other in only one respect: A "singleTask" activity allows other activities to be part of its task. It's always at the root of its task, but other activities (necessarily "standard" and "singleTop" activities) can be launched into that task. A "singleInstance" activity, on the other hand, permits no other activities to be part of its task. It's the only activity in the task. If it starts another activity, that activity is assigned to a different task — as if FLAG_ACTIVITY_NEW_TASK was in the intent.
“singleTask”和“singleInstance”活动只能开始一个任务。它们始终位于活动堆栈的根部。此外,设备一次只能保存一个活动实例——只有一项这样的任务。[...]
“singleTask”和“singleInstance”模式也仅在一个方面彼此不同:“singleTask”活动允许其他活动成为其任务的一部分。它始终是其任务的根,但其他活动(必须是“标准”和“单顶”活动)可以启动到该任务中。另一方面,“singleInstance”活动不允许其他活动成为其任务的一部分。这是任务中唯一的活动。如果它启动了另一个活动,该活动将被分配给不同的任务——就好像 FLAG_ACTIVITY_NEW_TASK 在意图中一样。
you can find a detailed explanation in the Android Developers' Guide
您可以在Android Developers' Guide 中找到详细说明
I hope this helps
我希望这有帮助
回答by Nick.D
I was having a similar problem and the proper way to handle this is to use the flags: Intent.FLAG_ACTIVITY_CLEAR_TOP and Intent.FLAG_ACTIVITY_SINGLE_TOP like so
我遇到了类似的问题,处理这个问题的正确方法是使用标志: Intent.FLAG_ACTIVITY_CLEAR_TOP 和 Intent.FLAG_ACTIVITY_SINGLE_TOP 像这样
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
From the documentation this will:
从文档中,这将:
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
如果设置了,并且正在启动的活动已经在当前任务中运行,那么不是启动该活动的新实例,而是将关闭它之上的所有其他活动,并且此 Intent 将被传递到(现在在顶部)旧活动作为新意图。
If set, the activity will not be launched if it is already running at the top of the history stack.
如果设置,如果活动已经在历史堆栈的顶部运行,则不会启动。
回答by user2965003
I had inconsistent behaviour between devices with some intents loosing extras and the MainActivity′s OnNewIntentand onCreatemethods both being called.
我在设备之间有不一致的行为,一些意图丢失了额外的东西,并且MainActivity 的OnNewIntent和onCreate方法都被调用了。
What did not work:
什么不起作用:
Manifest:
显现:
<activity android:name=".MainActivity"
android:launchMode="singleTask">
Service:
服务:
Intent notificationIntent = new Intent(this.getBaseContext(), MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("TEST", 1);
What did work:
什么工作:
Manifest:
显现:
<activity android:name=".MainActivity"
android:launchMode="singleTask">
Service:
服务:
PackageManager pm = getPackageManager();
Intent launchIntent = m.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID);
launchIntent.putExtra("TEST", 2);
回答by user1032613
You can simulate a launch intent(as if the user clicked on your app icon to launch it):
你可以模拟一个启动意图(就像用户点击你的应用程序图标来启动它一样):
val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
val contentIntent = PendingIntent.getActivity(context, 0, launchIntent, 0)
This way, you do nothave to mark your app as "singleTask" or "singleInstance" in Manifest (which would create other issues). Thus this should be the proper solution.
这样,您就不必在 Manifest 中将您的应用程序标记为“singleTask”或“singleInstance”(这会产生其他问题)。因此,这应该是正确的解决方案。
Note, however, the above solution may not work directly for you, due to an alleged android bug. Discussions about the android bug and a workaround can be found in this question.
但是请注意,由于所谓的 android 错误,上述解决方案可能无法直接为您工作。可以在此问题中找到有关 android 错误和解决方法的讨论。
回答by Nabil Mohammed Nalakath
Add this line to the corresponding activity in manifest file of your app.
将此行添加到应用程序清单文件中的相应活动。
android:launchMode="singleTask"
eg:
例如:
<activity
android:name=".Main_Activity"
android:label="@string/title_main_activity"
android:theme="@style/AppTheme.NoActionBar"
android:launchMode="singleTask" />
回答by nAkhmedov
I have just found a solution this issue: I created getPreviousIntentmethod and gave it to PendingIntent that`s all:
我刚刚找到了这个问题的解决方案:我创建了getPreviousIntent方法并将其提供给 PendingIntent 就是这样:
private Intent getPreviousIntent(Intent newIntent) {
final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final List<ActivityManager.RecentTaskInfo> recentTaskInfos = am.getRecentTasks(1024,0);
String myPkgNm = getPackageName();
if (!recentTaskInfos.isEmpty()) {
ActivityManager.RecentTaskInfo recentTaskInfo;
for (int i = 0; i < recentTaskInfos.size(); i++) {
recentTaskInfo = recentTaskInfos.get(i);
if (recentTaskInfo.baseIntent.getComponent().getPackageName().equals(myPkgNm)) {
newIntent = recentTaskInfo.baseIntent;
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
}
}
return newIntent;
}
回答by gnobal
I use:
我用:
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.setAction(Intent.ACTION_MAIN);
Not sure these are the values you need to set, but the answer is in those methods/flags.
不确定这些是您需要设置的值,但答案就在这些方法/标志中。

