Android - 清除任务标志不适用于PendingIntent

15 android android-intent android-notifications android-pendingintent

我有一个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);
Run Code Online (Sandbox Code Playgroud)

编辑1:

我在这里尝试了这个建议:清除任务中的所有活动?

notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
Run Code Online (Sandbox Code Playgroud)

但我仍然得到相同的结果.我的活动A在我的应用程序任务堆栈中开始,我按回去C,然后是B,然后是A.

我开始认为这在Android中是不可能的,或者在使用挂起的意图时是不可能的.

编辑2: 这不是需要什么标志的问题.更多的问题可能是错误的,标志似乎没有任何影响.

Vai*_*iya 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);
Run Code Online (Sandbox Code Playgroud)

要么

2)

       <activity 
       android:name=".ActivityA" 
       android:theme="@style/theme_noActionBar" 
       android:noHistory="true">
Run Code Online (Sandbox Code Playgroud)

要么

3)

<activity android:name=".ActivityA" android:launchMode="singleTop">
Run Code Online (Sandbox Code Playgroud)

  • 卸载并重新安装该应用程序使 OP 的原始代码对我有用,正如以下晦涩的答案之一所建议的 (CLEAR_TOP | NEW_TASK) (3认同)
  • ...或当“ PendingIntent”具有非零的“ requestCode”时。 (2认同)

Sim*_*ett 9

我在这方面遇到了很多问题,并认为我快疯了,直到我卸载/重新安装了我的应用程序,嘿,很快,代码按照 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);
Run Code Online (Sandbox Code Playgroud)

并且不断获得该应用程序的两个版本。在一台设备上卸载并重新启动另一台设备后,现在所有的行为都与单个实例的预期一致。希望这对你有帮助。


Jim*_*Jim 6

您遇到的问题与Android使用您PendingIntent和所需的创建新任务有关Intent.FLAG_ACTIVITY_NEW_TASK.换句话说,您想要使用的标志与在给定任务堆栈的上下文中启动活动有关.A PendingIntent通常没有上下文,因此您所看到的是为您的活动A挂起的意图创建的任务.

这是对文档的引用:

Android PendingIntent

对一系列PendingIntents中的第一个要求Intent.FLAG_ACTIVITY_NEW_TASK是问题.请注意,一系列未决意图的可具有相同的上下文使用"getActivities"方法的初始未决意图.

你是正确的,只有使用标志才能做你想做的事.您的代码是正确的,并且为了获得您想要的行为,您还需要超越intent标记.

还有许多其他方法,例如使用清单,运行服务,使用静态字段等来尝试管理您感兴趣的内容.除此之外,TaskStackBuilder如果你决定使用Manifest的路线,你可能会用来解决你的问题.还有许多其他解决方案不涉及标志,但您特别询问有关使用标志的问题.


Man*_*ani 5

您可以在清单文件中将launchModeActivityA 设置为singleTask。因为它ActivityA是您应用程序的根,所以它可以工作。

文档

系统在新任务的根部创建活动并将其意图路由到该活动。但是,如果活动的一个实例已经存在,则系统通过调用其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>
Run Code Online (Sandbox Code Playgroud)

编辑1:

由于您不想修改清单文件,因此我只能看到的选项是使用Intent.makeRestartActivityTask方法生成Intent。但是,这将重新启动ActivityA,而不是恢复现有实例。

Intent intent = Intent.makeRestartActivityTask(new ComponentName(this, ActivityA.class));
PendingIntent rIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
Run Code Online (Sandbox Code Playgroud)


小智 1

尝试使用 Intent 标志FLAG_ACTIVITY_CLEAR_TOP而不是清除任务。来自意图文档

如果设置,并且正在启动的活动已在当前任务中运行,则不会启动该活动的新实例,而是关闭该活动之上的所有其他活动,并且此 Intent 将传递到(现在在顶部)旧活动作为新意图。

例如,考虑一个由以下活动组成的任务:A、B、C、D。如果 D 使用解析为活动 B 的组件的 Intent 调用 startActivity(),则 C 和 D 将完成,并且 B 接收给定的 Intent ,结果堆栈现在为:A,B。