我有一个A>的任务堆栈B> C.我目前在C上,然后按下主页按钮。我收到通知,意图将我带到活动A.我按下通知,我在A,但如果我按回去,我会转到C,然后是B,然后是A.
我正在设置我的PendingIntent。有什么明显的错误吗?
final Intent notificationIntent = new Intent(mContext, ActivityA.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(myContext, 0, notificationIntent, 0);
编辑1:
我在这里尝试了这个建议:Clear all activities in a task?
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
但我仍然得到相同的结果。我的活动A在我的应用程序任务堆栈中开始,我按回去C,然后是B,然后是A再次。
我开始认为这在Android中是不可能的,或者在使用待处理的意图时是不可能的。
编辑2: 这不是需要什么标志的问题。更多的问题可能是错误,标志似乎没有效果。
答案 0 :(得分:15)
如果你使用解决方案1,那么只需从清单中删除launchMode="singleTask"
1)
final Intent notificationIntent = new Intent(mContext, ActivityA.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(myContext, 0, notificationIntent, 0);
OR
2)
<activity
android:name=".ActivityA"
android:theme="@style/theme_noActionBar"
android:noHistory="true">
OR
3)
<activity android:name=".ActivityA" android:launchMode="singleTop">
答案 1 :(得分:5)
您遇到的问题与Android使用PendingIntent
和所需的Intent.FLAG_ACTIVITY_NEW_TASK
创建新任务有关。换句话说,您想要使用的标志与在给定任务堆栈的上下文中启动活动有关。 PendingIntent
通常没有上下文,因此您看到的是为您的活动A挂起的意图创建的任务。
以下是对文档的引用:
要求PendingIntent
系列Intent.FLAG_ACTIVITY_NEW_TASK
中的第一个要求TaskStackBuilder
。请注意,使用“getActivities”方法,一系列待处理意图可以与初始待处理意图具有相同的上下文。
你是对的,你不可能只使用旗帜做你想做的事。您的代码是正确的,并且为了获得您想要的行为,您还需要超越意图标记。
还有许多其他方法,例如使用清单,运行服务,使用静态字段等来尝试管理您感兴趣的内容。除此之外,如果您决定使用Manifest,您可以使用{{1}}来解决您的问题。还有许多其他不涉及标志的解决方案,但您特别询问了使用标志。
答案 2 :(得分:4)
您可以在Manifest文件中将ActivityA的launchMode
设置为singleTask
。由于ActivityA
是您的应用程序的根,因此可以使用。
系统在新任务和路由的根目录下创建活动 意图。但是,如果活动的实例已经存在 存在,系统通过a将意图路由到现有实例 调用它的onNewIntent()方法,而不是创建一个新方法。
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
编辑1:
由于您不想修改Manifest文件,因此我只能看到使用Intent.makeRestartActivityTask方法生成Intent的选项。但是,这将重新启动ActivityA而不是恢复现有实例。
Intent intent = Intent.makeRestartActivityTask(new ComponentName(this, ActivityA.class));
PendingIntent rIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
答案 3 :(得分:3)
我遇到了很多这样的问题,并且在我卸载/重新安装我的应用程序之前我觉得自己很疯狂,并且嘿presto,代码按照Stack Overflow上的许多帖子工作。我正在做以下事情:
Intent i = new Intent(getApplicationContext(), MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
并且不断获得两个版本的App。在一台设备上卸载并重新启动另一台设备后,现在所有内容都会按照预期的单一实例运行。希望这会对你有所帮助。
答案 4 :(得分:2)
意图标志方面的解决方案如下:
launchMode:singleTask
使用以下代码块:
final Intent notificationIntent = new Intent(mContext, ActivityA.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(myContext, 0, notificationIntent, 0);
这里发生的事情是,当使用通知启动活动A时,通过Intent.FLAG_ACTIVITY_NEW_TASK
的定义,由于存在包含A的任务A&gt; B&gt; C,此任务也被提前破坏活动B和C和A以onNewIntent --> onRestart --> onStart --> onResume
如果某个任务已在您正在启动的活动中运行,则该任务将恢复到前台并恢复其上一个状态,并且该活动将在
中接收新的意图onNewIntent()
现在的原因是,为什么它仅仅与意图标志表现不佳就是,活动A没有以singleTask
模式启动,而Android在某种程度上不能维持它的状态。
答案 5 :(得分:1)
尝试使用Intent标志FLAG_ACTIVITY_CLEAR_TOP
而不是清除任务。来自Intent documentation:
如果设置,则正在启动的活动已在运行中 当前任务,然后而不是启动它的新实例 活动,其上的所有其他活动将被关闭 这个意图将作为一个传递到(现在在顶部)旧活动 新的意图。
例如,考虑一个由活动组成的任务:A,B,C,D。 如果D调用带有解析为的Intent的startActivity() 活动B的组成部分,然后C和D将完成,B接收 给定的Intent,导致堆栈现在为:A,B。
答案 6 :(得分:1)
我创建了一个演示项目作为您的描述,它可以像您想要的那样工作。
我不知道你是如何得到通知的,所以在我的项目中我使用BroadcastReceiver获取广播,然后在Receiver的onReceive()方法中显示Notification。我认为您可以将我的演示与您的项目进行比较以找到问题。顺便说一句,我的测试是在API 16下进行的。
这是我的演示: https://github.com/leoguo123/AndroidDemo
在存储库中:
测试项目包含3个活动(A&gt; B&gt; C),它可以在收到适当的广播时显示通知。 SendBroadcast项目负责发送广播。
生成通知的代码:
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
showNotification(context);
}
private void showNotification(Context context) {
Intent intent = new Intent(context, ActivityA.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationManager nmr = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle("Open A with B and C being closed");
builder.setContentText("Open A with B and C being closed");
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentIntent(pi);
builder.setAutoCancel(true);
Notification nt = builder.build();
nmr.notify(0, nt);
}
}
答案 7 :(得分:1)
我的解决方案代码:
public class MyApplication extends Application{
private static int activityCounter;
public Activity A,B,C;
public void incrementActivityCounter()
{
activityCounter++;
}
public void decrementActivityCounter()
{
activityCounter--;
if (activityCounter == 0)
{
A.finish();
B.finish();
C.finish();
}
}
}
public class A extends Activity{
@Override
protected void onStart()
{
super.onStart();
application.incrementActivityCounter();
}
@Override
protected void onStop()
{
application.decrementActivityCounter();
super.onStop();
}
}
答案 8 :(得分:0)
从上面尝试了所有建议,但都失败了,并从https://stackoverflow.com/a/24999724/4271334和https://stackoverflow.com/a/26592562/4271334的指南中提出了解决方案。 在清单中添加了以下两行
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
,然后使用
在NotificationCompat.Builder上设置PendingIntentmBuilder.setContentIntent(addBackStack(mContext,intent));
其中
public static PendingIntent addBackStack(final Context context, final Intent intent) {
TaskStackBuilder stackBuilder = TaskStackBuilder.create (context.getApplicationContext ());
stackBuilder.addNextIntentWithParentStack (intent);
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
return stackBuilder.getPendingIntent (0,PendingIntent.FLAG_UPDATE_CURRENT);
}
希望有人会得到帮助。