Android 从通知意图中删除数据

Android 从通知意图中删除数据,android,android-pendingintent,Android,Android Pendingintent,我对我的启动器活动的意图有异议。Scenerio是: 1.将意向表单通知服务发送到我的启动程序活动 PendingIntent contentIntent = PendingIntent.getActivity(this, TripLoggerConstants.PENDING_TRIPS_NOTIFICATION_ID, new Intent(this, MainActivity.class).putExtra("is_log", true), Intent.FLAG_ACTIVITY_CLE

我对我的启动器活动的意图有异议。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);
二,。在我的主要活动中,我得到了这个意图。代码是:

if(this.getIntent().getExtras()!=null){

        boolean isLogNewTripScreen  = (boolean)this.getIntent().getExtras().getBoolean("is_log");

    }
    }

三,。这很好,但当我来自notification service时,但当我从notification service启动时,intent中的数据仍然存在。如何从intent中删除该数据。

编辑:我创建了一个示例应用程序来测试此问题和可能的解决方案。以下是我的发现:

如果您从带有附加功能的通知中启动应用程序,然后从最近的任务列表中选择它返回到应用程序,Android将以与从通知中启动应用程序相同的方式再次启动应用程序(即:带有附加功能)。这要么是一个bug,要么是一个特性,这取决于你问谁

您需要添加额外的代码来处理这种情况。我可以提出两个建议:

1。使用
标记活动\u从最近的活动中排除\u

创建通知时,在
Intent
中设置标志
Intent.flag\u ACTIVITY\u EXCLUDE\u FROM\u RECENTS
。然后,当用户选择通知并从通知启动应用程序时,这将不会在最近的任务列表中为此任务创建条目。此外,如果此应用程序的最近任务列表中有一个条目,则该条目也将被删除。在这种情况下,用户将无法从最近的任务列表返回此任务。这可以通过消除用户从最近任务列表中启动应用程序的可能性(但仅当应用程序已从通知中启动时)来解决您的问题

2。从历史记录中检测
标记活动\u已启动\u

当用户从最近的任务列表中启动应用程序时,Android会在传递给启动活动的
onCreate()
Intent
中设置标志
Intent.flag\u ACTIVITY\u LAUNCHED\u from\u HISTORY
。您可以在
onCreate()
中检测到此标志的存在,然后您就知道应用程序是从最近的任务列表启动的,而不是从通知启动的。在这种情况下,您可以忽略
Intent
中的额外内容仍然包含数据这一事实

选择最适合您的应用程序工作流的解决方案。谢谢你的提问,这是一个有趣的挑战,需要解决:-)


其他信息:

您创建的
挂起内容不正确。你在打电话吗

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\u ACTIVITY\u CLEAR\u TOP
作为
getActivity()
的第四个参数。但是,该参数应该是
pendingent
标志。如果您想在
意图
上设置
标记活动\u清除\u顶部
,您需要这样做:

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,将其内容发送到Web服务,如果正确,用片段2替换它。当用户按back时,OnBack将在调用完成活动中按下。如果用户在列表中再次选择应用程序,则它将打开片段1而不是片段2

我解决了签入onBackPressed是否包含一个字段指示片段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);

我测试了stackoverflow的所有答案,但没有运气,对我有效的是这个。创建一个助手类来检查活动标志。或者是一个函数,这无关紧要

 object FlagHelper {
fun notLaunchedFromNotification(activity: AppCompatActivity): Boolean {
    return activity.intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
}
}

然后使用以下代码。它返回一个布尔值,因此当它为false时,您可以检查intent extras

val notLaunchedFromNotification = FlagHelper.notLaunchedFromNotification(this)
将android:launchMode=“singleInstance”添加到您的启动程序活动中
然后在启动活动时使用flag Intent.flag\u ACTIVITY\u EXCLUDE\u FROM\u RECENTS

你说当你从not notification service启动应用程序时,Intent extras仍然存在。正在调用
onCreate()
?请更详细地解释此问题。是的,我从最近的应用程序中启动应用程序。和onCreate()从开始调用,但主要活动的意图不是空的。请告诉我,如果您通过选择主屏幕上的图标(或已安装应用程序列表中的图标)而不是从应用程序列表中启动应用程序(使用通知后),会发生什么情况“最近的应用程序”David当我从最近的应用程序中选择应用程序时(长按“主页”按钮),我从通知服务发送的意向数据不是空的,这是错误的,并产生问题,但当我从应用程序中打开应用程序时,它工作正常(在这种情况下,意向数据也是空的)。这种情况对我来说似乎有些熟悉。我想这是一个Android错误。我会做更多的研究,然后再回来找你。谢谢,这对我帮助很大。我使用“(intent.getFlags()&intent.FLAG_ACTIVITY_launted_FROM_HISTORY)!=0“以检测应用程序是否从历史记录中启动。如果用户像往常一样运行应用程序(从应用程序列表中),则此操作似乎不起作用,不是最近的tasks@LeiGuo请发布示例代码,因为我无法让它发挥作用,而此代码可能会解决问题,包括解释如何以及为什么解决问题会真正有助于提高您的帖子质量,并可能导致更多的投票。请记住,您是在f中为读者回答问题的未来,不仅仅是现在提问的人。请在回答中添加解释,并说明适用的限制和假设。
PendingIntent contentIntent = PendingIntent.getActivity(this, TripLoggerConstants.PENDING_TRIPS_NOTIFICATION_ID, new Intent(this, MainActivity.class).putExtra("is_log", true), Intent.FLAG_ACTIVITY_CLEAR_TOP);