简体   繁体   English

从通知中恢复活动

[英]resuming an activity from a notification

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? 有没有办法创建一个Intent来做到这一点?

I've solved this issue by changing the launchMode of my activity to singleTask in 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. “singleTask”和“singleInstance”活动只能开始一项任务。 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. “singleTask”和“singleInstance”模式在一个方面也各不相同:“singleTask”活动允许其他活动成为其任务的一部分。 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. 另一方面,“singleInstance”活动不允许其他活动成为其任务的一部分。 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. 如果它启动另一个活动,则该活动将分配给另一个任务 - 就像FLAG_ACTIVITY_NEW_TASK在意图中一样。

you can find a detailed explanation in the Android Developers' Guide 您可以在Android开发人员指南中找到详细说明

I hope this helps 我希望这有帮助

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: 从文档中,这将:

FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_CLEAR_TOP

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传递给(现在开启) top)旧活动作为新的意图。

FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_SINGLE_TOP

If set, the activity will not be launched if it is already running at the top of the history stack. 如果设置,则如果活动已在历史堆栈的顶部运行,则不会启动该活动。

I have just found a solution this issue: I created getPreviousIntent method 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;
}

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" />

I had inconsistent behaviour between devices with some intents loosing extras and the MainActivity´s OnNewIntent and onCreate methods both being called. 我在设备之间存在不一致的行为,其中一些意图丢失额外的东西,MainActivity的OnNewIntentonCreate方法都被调用。

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);

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. 不确定这些是您需要设置的值,但答案是在那些方法/标志中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM