9

我的启动器活动的意图有问题。场景是: 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. 在我的 MainActivity 中,我得到了这个意图。代码是:

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

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

    }
    }

3.这个工作正常但是当我来自通知服务时,但是当我从非通知服务启动时,意图中的数据仍然存在。我如何从意图中删除该数据。

4

4 回答 4

35

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

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

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

1.使用FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

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

2.检测FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

当用户从最近的任务列表中启动您的应用程序时,Android会Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY在您的启动活动中设置标志。您可以检测到此标志的存在,然后您知道该应用程序已从最近的任务列表中启动,而不是从通知中启动。在这种情况下,您可以忽略额外内容中仍然包含数据的事实。IntentonCreate()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作为第四个参数传递给getActivity(). 但是,该参数应该是PendingIntent标志。如果你想在FLAG_ACTIVITY_CLEAR_TOP上设置Intent,你需要这样做:

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);
于 2013-11-06T18:37:18.450 回答
0

我已经测试了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
}

}

然后使用如下代码。它返回一个布尔值,因此您可以在它为假时检查意图附加值

val notLaunchedFromNotification = FlagHelper.notLaunchedFromNotification(this)
于 2021-01-07T10:43:19.203 回答
0

我注意到使用片段。我在 Activity A 中读取了打开片段 1 的二维码,将其内容发送到 Web 服务,如果正确,则将其替换为片段 2。当用户按下返回时,Activity A 中的 onBackPressed 调用完成。如果用户在列表中再次选择该应用程序,它将打开片段 1 而不是片段 2。

如果 extra 包含指示片段 2 已打开的字段,我解决了检查 onBackPressed 的问题。如果为 true,则调用 moveTaskToBack(true) 而不是 finish()

活动一

@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);
于 2018-01-09T18:55:23.810 回答
0

将 android:launchMode="singleInstance" 添加到您的启动器活动中,然后在启动活动时使用标志 Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

于 2021-05-06T17:16:54.930 回答