如何从通知状态栏打开最近的活动?

6
我希望通过在状态栏中点击通知来打开最近启动的活动。假设我启动了Activity A(我的应用的主要活动),这个活动会向通知状态栏发送一个通知。Activity A还会打开Activity B,B会打开另一个活动C。从C中,我按下了主页按钮。现在我想再次回到我的应用程序,所以我从通知栏中点击了通知(由A发送)。在这里,通知应该启动活动C,因为它是最后一个打开的活动。
我已经搜索过但没有找到合适的答案。提前感谢。

1
你尝试过什么?(http://mattgemmell.com/2008/12/08/what-have-you-tried/) - adneal
为什么不设计成在Intent中传入额外信息,然后Activity根据需要处理它呢? - JoxTraex
问题与此问题相关 http://stackoverflow.com/questions/3079652/custom-notification - OnkarDhane
https://dev59.com/Sm035IYBdhLWcg3wTuJu#5502950 - alex
因为工作必须在打开活动之前完成。 - An-droid
在这里,这是最佳解决方案:https://dev59.com/2o3da4cB1Zd3GeqPuxIX - nAkhmedov
4个回答

24

前几天我得到了非常简单的解决方案来解决我的问题。我们可以采用以下简单方法,而不是遍历recentTasks并获取我们的任务,然后通过它获取baseIntent

Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.setAction(Intent.ACTION_MAIN);

baseIntent 包含与上述 Intent 相同的参数。因此,不必从 recentTasks 获取 baseIntent,而是可以使用上述代码。

这个 notificationIntent 然后将传递给 pendingIntent 供进一步使用。

前提条件是:MainActivity 是我们启动应用时的第一个活动,并且在 AndroidManifest.xml 中它必须包含 CATEGORY_LAUNCHERACTION_MAINIntentFilters


运行得非常好,我使用了一个登录活动,根据一些参数打开另一个活动。现在,当用户通过点击通知打开应用程序时,它会重新打开应用程序而不会堆叠活动! - Oritm
1
我想在清单文件中添加android:launchMode="singleTop",并在意图中使用Intent.FLAG_ACTIVITY_NEW_TASK。 - shantanu

7

由于在搜索后没有得到任何答案,我停止了尝试,但几天前我重新开始尝试,并找到了解决方案。:) 我在这里放置它。

但首先,我只想重新定义我的问题,即:“从状态通知栏将后台任务转移到前台”,即当我按home键将我的应用程序置于后台,然后使其出现在前台时,所有活动都应以与应用程序堆栈中相同的顺序出现在前台。

为此,我需要一个Pending Intent,每当触发时,就会将我的应用程序带到前台。

在这里,当我的应用程序启动时,会在状态栏上放置一个通知,该通知会一直保留到我的应用程序在设备上运行。

因此,这是我尝试的代码:

NotificationManager nm = (NotificationManager) getSystemService(context.NOTIFICATION_SERVICE);
Notification notification = new Notification();
notification.flag = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;

Intent nIntent = new Intent();

final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

final List<RecentTaskInfo> recentTaskInfos = am.getRecentTasks(1024,0);
String myPkgNm = getPackageName();

if (!recentTaskInfos.isEmpty()) {
     RecentTaskInfo recentTaskInfo;
     final int size = recentTaskInfo.size();
     for (int i=0;i<size;i++) {
         recentTaskInfo = recentTaskInfos.get(i);
         if (recentTaskInfo.baseIntent.getComponent().getPackageName().equals(myPkgNm)) {
             nIntent = recentTaskInfo.baseIntent;
             nIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         }
     }
 }
 PendingIntent pi = PendingIntent.getActivity(this, 0, nIntent, 0);
 notification.setLatestEventInfo(getContext(), "some Title", "some text", pi);
 nm.notify(0,notification); 

这里的主要关键是baseIntent,其文档说明如下: 用于启动任务的原始 Intent。您可以使用此 Intent 重新启动该任务(如果它不再运行),或将当前任务前置。 FLAG_ACTIVITY_NEW_TASK 的文档说明如下: 当使用此标志时,如果已经为您现在要启动的活动运行了一个任务,则不会启动新的活动;相反,当前任务将仅以其上次状态显示在屏幕前面。 我最初使用了这个方法,但它并没有按照所说的那样工作,有很多问题。
无论如何,到目前为止,我发现这种方式对于像 Android 主屏幕上的图标一样将任务带到前面非常好。
但请告诉我这种方法的缺点,以便我可以改进。
:)

Content.ACTIVITY_SERVICE 应该是 Context... 无法编辑,因为我需要最少 6 个字符的更改 :| - Recognizer
@Foobar:按照你的建议进行修改。 ;) - ChuongPham
1
太棒了。但是我想说,你必须添加 <uses-permission android:name="android.permission.GET_TASKS" />。 - Vyacheslav

5

你尝试过这个吗:

final Intent intent = new Intent(context, YourActivity.class)
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);

上述代码指示Android打开最后一个活动,无论它是主要活动还是偏好活动[当前在前台],这些活动是您用来创建/启动通知栏图标的。

ACTION_MAINCATEGORY_LAUNCHER分别指向您的AndroidManifest.xml文件中的<action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/>指令。

2

一直对我有用。

清单

launchMode="singleTop" #For Launcher activity
never use "singleTask" as a launchMode
set no launchMode for other activities. (if not needed)

Notification Intent

Intent notificationIntent = new Intent();
notificationIntent.setClass(this, LaucherActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接