单击通知时如何保留当前的返回堆栈(或任务)?
Posted
技术标签:
【中文标题】单击通知时如何保留当前的返回堆栈(或任务)?【英文标题】:How to preserve current back stack (or task) when notification is clicked? 【发布时间】:2017-06-27 19:52:06 【问题描述】:在我的应用程序中,我创建了一个启动 Details Activity 的通知。我想将此活动添加到 当前 任务(或返回堆栈)的顶部。例如,我希望应用程序任务(回栈)的行为如下:
但我明白了:
我没有使用FLAG_ACTIVITY_CLEAR_TASK
和FLAG_ACTIVITY_NEW_TASK
标志。我该怎么办?
编辑:第一张图片只是一个例子。我认为问题的标题是完全明确的。我想在当前堆栈顶部添加 Details Activity,而不是从新任务开始。
这就是我创建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 我现在做了,但没有结果。
你解决了吗?我也有同样的问题。每当我从通知开始活动时,它都会清除我当前的后台堆栈。
@AndreiVinogradov 不完全是,但我已经设法使用任务关联性解决了这个问题。阅读我的答案below。
是的,不完全一样,但我也发现你的方式最接近所需的行为。请接受您自己的答案,以使主题更加清晰。
【参考方案1】:
我找到了这个链接:Preserving Navigation when Starting an Activity。虽然它没有为我的问题提供确切的解决方案,但它产生了预期的结果。
该链接描述了我们应该使用不同的affinity在一个新任务中启动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);
这应该可以解决您的目的。
更多详情请参考此链接Back to main activity from notification-created activity
【讨论】:
我认为这是要走的路,但我已经对问题进行了更多解释。我想将 DetailsActivity 添加到 current 堆栈,无论它是什么。我认为您的解决方案总是给出 Main > Note > Details。是这样吗? 是的,我的解决方案将始终提供此堆栈-- Main > Note > Details。它实际上启动了新的 DetailActivity,在后台堆栈中有两个活动意图。这两个意图将被触发并创建两个新的按下后退按钮时的活动实例。但这不会将活动添加到当前堆栈。【参考方案3】:您需要使用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 开始。【参考方案4】:我想要完全相反的(这是默认行为)。
事实证明,在通知启动的 Activity 上设置 noHistory="true"
或/和调用 finish()
,保留现有的 backstack。
所以基本上解决方案是要么不将 Activity 保留在后台堆栈中,要么创建一个不会保留的“NotificationActivity”,它将负责启动您想要的 Activity(在您的示例中为 DetailsActivity)。
【讨论】:
【参考方案5】:android docs 的解决方案可能对您有用。它对我有用,但我只有一个父子返回堆栈。
与父母关系的清单:
<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);
【讨论】:
以上是关于单击通知时如何保留当前的返回堆栈(或任务)?的主要内容,如果未能解决你的问题,请参考以下文章
Android 通知单击保持堆栈并在需要时将应用程序置于最前面。如果特定活动在顶部,则传递数据
在 iOS 上单击时,Phonegap 插件推送通知保留在托盘中