10

I have issue in intent of my launcher activity.Scenerio is: 1. Send intents form notification service to my launcher activity

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. In my MainActivity i getting this intent. code is:

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

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

    }
    }

3. this work fine but when i come from notification service,but when i launch from not notification service ,that data in intentis still there.How can i remove that data from intent.

user2106897
  • 529
  • 1
  • 5
  • 11
  • You say that when you launch the app _from not notification service_ the Intent extras are still there. Is `onCreate()` being called? Please explain this problem in more detail. – David Wasser Nov 06 '13 at 18:37
  • yes i launch app from home button from recent apps.and onCreate() calls from start but intent of Mian activity is not null – user2106897 Nov 06 '13 at 18:51
  • Please tell me what happens if you launch the app (after using the notification) by selecting the icon on the HOME screen (or from the list of installed apps) and not from the list of "recent apps" – David Wasser Nov 06 '13 at 19:04
  • David when i select app from recent apps(on long press on home button) the data in intent which i send from notification service is not null which is wrong and create issue but when i open app from application it work fine (data in intent in this case is also null). – user2106897 Nov 07 '13 at 04:55
  • This situation sounds vaguely familiar to me. I think this is an Android bug. I'll do a bit more research and come back to you. – David Wasser Nov 07 '13 at 07:39
  • Figured it out. Added a detailed explanation with solution alternatives. – David Wasser Nov 07 '13 at 09:48

4 Answers4

42

EDIT: I've created a sample application to test this problem and possible solutions. Here are my findings:

If you launch your app from a notification with extras and then later return to your app by selecting it from the list of recent tasks, Android will launch the app again the same way it was launched from the notification (ie: with the extras). This is either a bug or a feature, depending on who you ask.

You'll need to add additional code to deal with this situation. I can offer 2 suggestions:

1. Use FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

When you create your notification, set the flag Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS in the Intent. Then, when the user selects the notification and launches the app from the notification, this will not create an entry for this task in the list of recent tasks. Also, if there was an entry in the list of recent tasks for this application, that entry will also be removed. In this case, it will not be possible for the user to return to this task from the list of recent tasks. This solves your problem by removing the possibility that the user launches the app from the list of recent tasks (but only when the app has been launched from the notification).

2. Detect FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

When the user launches your app from the list of recent tasks, Android sets the flag Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY in the Intent that is passed to onCreate() of your launch activity. You can detect the presence of this flag in onCreate() and then you know that the app has been launched from the recent tasks list and not from the notification. In this case, you can just ignore the fact that the extras in the Intent still contain data.

Choose the solution that best suits the workflow for your application. And thanks for the question, this was an interesting challenge to solve :-)


Additional information:

You are creating the PendingIntent incorrectly. You are calling

PendingIntent contentIntent = PendingIntent.getActivity(this,
        TripLoggerConstants.PENDING_TRIPS_NOTIFICATION_ID,
        new Intent(this, MainActivity.class).putExtra("is_log", true),
        Intent.FLAG_ACTIVITY_CLEAR_TOP);

You are passing Intent.FLAG_ACTIVITY_CLEAR_TOP as the 4th parameter to getActivity(). However, that parameter should be PendingIntent flags. If you want to set FLAG_ACTIVITY_CLEAR_TOP on the Intent, you need to do it this way:

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);
David Wasser
  • 93,459
  • 16
  • 209
  • 274
0

I noticed that using fragments. I read a QR Code in Activity A that opens fragment 1, send its content to a webservice and if goes right, replace it with fragment 2. When user press back, the onBackPressed in Activity A call finish. If user select the app again in the list, it was opening fragment 1 instead of fragment 2.

I solved that checking in onBackPressed if extra contains a field indicating that fragment 2 was already opened. If true, moveTaskToBack(true) is called instead of finish()

Activity A

@Override
public void onBackPressed() {
 Bundle extras = getIntent().getExtras();
 if(extras.containsKey(Constants.TICKET_DONT_SHOW_QRCODE_SCREEN)){
    moveTaskToBack(true);
 }else {
    finish();
 }
}

Fragment 2

Intent mainIntent = getActivity().getIntent();
mainIntent.putExtra(Constants.TICKET_DONT_SHOW_QRCODE_SCREEN, true);
getActivity().setIntent(mainIntent);
AmandaHLA
  • 119
  • 1
  • 2
0

I've tested all the answers of stackoverflow with no luck, what worked for me was this. Create a helper class to check the activity flags. Or a function, it does not matter.

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

}

Then use as the following code. It returns a boolean so you can check the intent extras when it's false

val notLaunchedFromNotification = FlagHelper.notLaunchedFromNotification(this)
Dantalian
  • 561
  • 6
  • 15
0

Add android:launchMode="singleInstance" to your launcher activity and then Use flag Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS while starting your activity

  • While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Kevin M. Mansour May 06 '21 at 22:55