Android: Activity is using old intent if launching

2020-05-22 01:47发布

问题:

I'm implementing GCM. My app has two activities, say A and B. I'm using this code to launch B from the NotificationBar:

long when = System.currentTimeMillis();
NotificationManager notificationManager =
    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String title = context.getString(R.string.app_name);        
Notification notification = new Notification(R.drawable.app_notification_icon, "De Centrale", when);//message
Intent notificationIntent = new Intent(context, B.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); //|Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(context, title, msg, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);

NotificationBar opens Activity B with an Intent, say 'B-notification-intent', then I open Activity A from B using Back button, then again I launch B from A having a new Intent (say 'B-A-intent'). I use the code below:

intent = new Intent(this, B.class); 
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);              
startActivity(intent);

And then I get New Data in B (i.e the screen of B is refreshed). But if I press the Home button and then I launch the application from Recent app then I get older B screen with 'B-notification-intent'. Instead, I want the latest Intent, i.e 'B-A-intent'. I'm using this code in B:

@Override
protected void onCreate(Bundle b)
{
    fetchDataFromDB(getIntent());           
}

@Override
protected void onNewIntent(Intent intent)
{
    fetchDataFromDB(intent);        
}

So anybody please help me getting my current screen (intent).

回答1:

I also noticed that sometimes an Activity's onCreate() was getting stale Intents when launched from Recents, but there is a way to check for that so you can handle the Intent appropriately.

JAVA:

protected boolean wasLaunchedFromRecents() {
    return (getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY;
}

Kotlin:

fun wasLaunchedFromRecents(): Boolean {
    val flags: Int = intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
    return flags == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
}

In my humble opinion, that flag is poorly named (other flags referencing the Recents list actually use that word, e.g. FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, FLAG_ACTIVITY_RETAIN_IN_RECENTS) and the documentation was never updated to reflect the fact that many popular Android devices have a dedicated button for Recents:

This flag is not normally set by application code, but set for you by the system if this activity is being launched from history (longpress home key).

(N.B. I realize that you solved your issue another way years ago, but this question is one of the top search results for 'android old intent recent' and none of the other related questions mention this flag, so hopefully this Answer can help someone else.)