从通知意图中删除数据



我的启动器活动有问题。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

最新更新