当通知被点击时如何保留当前的后台栈(或任务)?

10
在我的应用程序中,我创建了一个通知,它启动了详细信息活动(Details Activity)。我想将此活动添加到当前任务(或后退栈)的顶部。例如,我希望应用程序任务(后退栈)表现如下:

enter image description here

但我得到了这个:

enter image description here

我没有使用FLAG_ACTIVITY_CLEAR_TASKFLAG_ACTIVITY_NEW_TASK标记。我该怎么办?
编辑:第一张图片只是一个示例。我认为问题的标题已经非常明确了。我想在当前堆栈顶部添加详细信息活动,而不是启动一个新任务。
这是我创建PendingIntent的方法:
    // Details activity intent
    Intent intent = new Intent(context, DetailsActivity.class);
    intent.putExtra(Com.KEY_ID, event.getId());
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
            intent, PendingIntent.FLAG_UPDATE_CURRENT);

这是清单文件:

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name_system"
        android:launchMode="singleTop"
        android:theme="@style/AppTheme.NoActionBar">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity
        android:name=".NoteActivity"
        android:label="@string/app_name_system"
        android:theme="@style/AppTheme.NoActionBar"
        android:windowSoftInputMode="stateHidden" />

    <activity
        android:name=".DetailsActivity"
        android:launchMode="singleTop"
        android:label="@string/app_name_system"
        android:theme="@style/AppTheme.NoActionBar" />

你尝试设置意图标记 Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP 了吗? - sup4eli
@sup4eli 我现在已经做了,但没有结果。 - h.nodehi
你解决了吗?我也遇到了同样的问题。每当我从通知启动活动时,它会清除我的当前返回堆栈。 - Andrei Vinogradov
@AndreiVinogradov 不完全是这样,但我已经成功地利用任务亲和性解决了问题。请查看我的答案 以下链接 - h.nodehi
是的,它不完全相同,但我也发现你的方法最接近所需的行为。请接受您自己的答案以使主题更清晰。 - Andrei Vinogradov
5个回答

4
我找到了这个链接:在启动Activity时保留导航。虽然它没有提供我问题的确切解决方案,但它得到了期望的结果。
该链接描述了我们应该使用不同的亲和性在一个新任务中启动DetailsActivity
清单文件:
    <activity
        android:name=".DetailsActivity"
        android:excludeFromRecents="true"
        android:label="@string/app_name_system"
        android:launchMode="singleTop"
        android:taskAffinity=""
        android:theme="@style/AppTheme.NoActionBar" />

PendingIntent的创建:

    Intent intent = new Intent(context, DetailsActivity.class);
    intent.putExtra(Com.KEY_ID, event.getId());
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
            intent, PendingIntent.FLAG_UPDATE_CURRENT);

2

你可以使用PendingIntent.getActivities来构建你的任务栈,而不是使用PendingIntent.getActivity

Intent mainActivityIntent = new Intent(context,MainActivity.class);
mainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Intent noteActivityIntent= new Intent(context,NoteActivity.class);
noteActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Intent detailActivityIntent= new Intent(context,DetailActivity.class);

final PendingIntent pendingIntent = PendingIntent.getActivities(ctx, UNIQUE_REQUEST_CODE++,
            new Intent[] {mainActivityIntent,noteActivityIntent,detailActivityIntent},PendingIntent.FLAG_UPDATE_CURRENT);

这应该能解决你的问题。

参考此链接以获取更多详细信息:从通知创建的活动返回主活动


1
我认为这是正确的方法,但我已经在问题后附加了更多的解释。我想将DetailsActivity添加到当前堆栈中,无论它是什么。我认为你的解决方案总是会给出Main > Note > Details。是这样吗? - h.nodehi
是的,我的解决方案将始终给出这个堆栈--主要>注释>详细信息。它实际上会在后台堆栈中启动具有两个活动意图的新DetailActivity。这两个意图将被触发,并将在按下返回按钮时创建两个新的活动实例。但这不会将活动添加到当前堆栈中。 - Syed Taruf Naqvi

1
你需要使用getActivities(),并在第三个参数中指定整个导航路径,该参数接受一个意图数组。您需要按照应用程序导航的顺序构建该数组,即最左边是根/主要活动,从那里进一步下降级别。
类似这样的东西
Intent mainActivityIntent = new Intent(context, MainActivity.class);
mainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // only specify new task flag for MainActivity

Intent noteActivityIntent= new Intent(context,NoteActivity.class);

Intent detailsActivityIntent = new Intent(context, DetailsActivity.class);

PendingIntent pendingIntent = PendingIntent.getActivities(context, 0,
            new Intent[] {mainActivityIntent,noteActivityIntent,detailsActivityIntent},PendingIntent.FLAG_UPDATE_CURRENT);

请注意:如果您的应用程序已经处于活动状态,当您按下返回键时,Android 将带您返回到您的 NoteActivity,然后是 MainActivity。如果这些活动已经存在,则它们将被重新启动,否则将创建新的活动。

这张图片只是一个例子。我想将DetailsActivity添加到当前堆栈的顶部,而不是始终从Main > Note > Details开始。 - h.nodehi

0

我想要的是完全相反的(这是默认行为)。

事实证明,设置noHistory="true"或/和在由通知启动的Activity上调用finish()可以保留现有的后退堆栈。

因此,解决方案基本上是要么不将Activity保留到后退堆栈中,要么创建一个“NotificationActivity”,它不会被保留,并负责启动您想要的Activity(例如DetailsActivity)。


0

来自Android文档的解决方案可能适用于您。对我有用,但我只有一个单一的父子回退栈。

具有父关系的清单:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<!-- MainActivity is the parent for NoteActivity-->
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity" />
    ...
</activity>

<!-- NoteActivity is the parent for DetailsActivity -->
<activity
    android:name=".DetailsActivity "
    android:parentActivityName=".NoteActivity " />
    ...
</activity>

创建待定意图:

// Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this, DetailsActivity.class);

// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);

// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

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