我的启动器活动有问题。Scenerio是:1. 向我的启动器活动发送意向表单通知服务
PendingIntent contentIntent = PendingIntent.getActivity(this, TripLoggerConstants.PENDING_TRIPS_NOTIFICATION_ID, new Intent(this, MainActivity.class).putExtra("is_log", true), Intent.FLAG_ACTIVITY_CLEAR_TOP);
2. 在我的主活动中,我得到了这个意图。 代码是:
if(this.getIntent().getExtras()!=null){
boolean isLogNewTripScreen = (boolean)this.getIntent().getExtras().getBoolean("is_log");
}
}
3.这工作正常,但是当我来自通知服务时,但是当我从非通知服务启动时,意图中的数据仍然存在。如何从意图中删除该数据。
编辑:我创建了一个示例应用程序来测试此问题和可能的解决方案。以下是我的发现:
如果您从包含附加内容的通知启动应用,然后通过从最近任务列表中选择应用返回到应用,Android 将再次启动应用,其启动方式与从通知启动时相同(即:使用附加内容)。这要么是错误,要么是功能,具体取决于您询问的对象。
您需要添加其他代码来处理这种情况。我可以提供2个建议:
1. 使用FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
创建通知时,请在Intent
中设置标志Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
。然后,当用户选择通知并从通知启动应用时,这不会在最近任务列表中为此任务创建条目。此外,如果此应用程序的最近任务列表中有一个条目,则该条目也将被删除。在这种情况下,用户将无法从最近任务列表中返回到此任务。这通过消除用户从最近任务列表中启动应用的可能性(但仅当应用已从通知启动时)来解决您的问题。
2. 检测FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
当用户从最近任务列表中启动您的应用时,Android 会在传递给您的启动活动onCreate()
的Intent
中设置标志Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
。您可以在onCreate()
中检测到此标志的存在,然后您知道应用已从最近的任务列表而不是从通知中启动。在这种情况下,您可以忽略Intent
中的附加内容仍然包含数据的事实。
选择最适合您应用工作流程的解决方案。感谢您的问题,这是一个有趣的挑战:-)
附加信息:
您创建PendingIntent
不正确。您正在呼叫
PendingIntent contentIntent = PendingIntent.getActivity(this,
TripLoggerConstants.PENDING_TRIPS_NOTIFICATION_ID,
new Intent(this, MainActivity.class).putExtra("is_log", true),
Intent.FLAG_ACTIVITY_CLEAR_TOP);
您正在将Intent.FLAG_ACTIVITY_CLEAR_TOP
作为第 4 个参数传递给 getActivity()
。但是,该参数应为PendingIntent
标志。如果要在Intent
上设置FLAG_ACTIVITY_CLEAR_TOP
,则需要这样做:
PendingIntent contentIntent = PendingIntent.getActivity(this,
TripLoggerConstants.PENDING_TRIPS_NOTIFICATION_ID,
new Intent(this, MainActivity.class).putExtra("is_log", true)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);
我注意到使用片段。我在活动 A 中读取了一个 QR 码,该二维码打开片段 1,将其内容发送到网络服务,如果正确,则将其替换为片段 2。当用户按"后退"时,活动 A 中的"上后压"调用完成。如果用户在列表中再次选择应用,它将打开片段 1 而不是片段 2。
我解决了检查 onBackPress 是否包含指示片段 2 已打开的字段。如果为 true,则调用 moveTaskToBack(true) 而不是 finish()
活动A
@Override
public void onBackPressed() {
Bundle extras = getIntent().getExtras();
if(extras.containsKey(Constants.TICKET_DONT_SHOW_QRCODE_SCREEN)){
moveTaskToBack(true);
}else {
finish();
}
}
片段 2
Intent mainIntent = getActivity().getIntent();
mainIntent.putExtra(Constants.TICKET_DONT_SHOW_QRCODE_SCREEN, true);
getActivity().setIntent(mainIntent);
我已经测试了堆栈溢出的所有答案,但没有运气,对我有用的是这个。创建帮助程序类以检查活动标志。或者一个函数,没关系。
object FlagHelper {
fun notLaunchedFromNotification(activity: AppCompatActivity): Boolean {
return activity.intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
}
}
然后用作以下代码。它返回一个布尔值,因此您可以在它为假时检查意图附加内容
val notLaunchedFromNotification = FlagHelper.notLaunchedFromNotification(this)
将 android:launchMode="singleInstance" 添加到您的启动器活动中,然后在开始活动时使用标志Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS