Search code examples
androidandroid-intentnotificationsbundlelifecycle

Sending parameters from a notification to a different activity?


I have a follow on question to the question answered here: How to send parameters from a notification-click to an activity?

So, I have 3 activities, A, B, and C. An alarm (timer) starts when the user gets to activity C. After X amount of time, a notification appears in the status bar. Below is how I launch the notification. "MainActivity.class" is activity A. However, launching the notification in this way restarts the application in whatever activity the user was in when the closed it. So, if they were in activity C when the app closed and they click on the notification, the app will resume to activity C.

Intent notificationIntent = new Intent( this, MainActivity.class );
notificationIntent.setAction( Intent.ACTION_MAIN );
notificationIntent.addCategory( Intent.CATEGORY_LAUNCHER );
notificationIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED );
notificationIntent.putExtra( NotifyService.NOTIFICATION_INTENT, true );

PendingIntent contentIntent = PendingIntent.getActivity( this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT );

Notification notification = new Notification.Builder( this )
.setContentTitle( title )
.setContentText( text )
.setTicker( ticker )
.setSmallIcon( R.drawable.ic_launcher )
.setWhen( time )
.setContentIntent( contentIntent )
.setAutoCancel( true )
.setDefaults( Notification.DEFAULT_ALL )
.build();

I have this in the manifest for activities A, B, and C: android:launchMode="singleTop". I also have the following code in each activity.

@Override
public void onNewIntent( Intent intent )
{
    super.onNewIntent( intent );

    Bundle extras = intent.getExtras();

    if( extras != null )
    {
        Boolean startedFromNotification = extras.getBoolean( NotifyService.NOTIFICATION_INTENT );

        if( startedFromNotification )
        {
            // Do something
        }
    }
}

Now, if the user was in activity A when they closed the app, then onNewIntent gets called in that activity when they click on the notification (working as expected). But, if they were in activity B or C, not only does onNewIntent in those activities not get called, but the extra I put in there (NotifyService.NOTIFICATION_INTENT) is also missing.

Is there anyway to pass the notification intent extras to the app when it resumes to activity B or C?


Solution

  • I was lead to an answer via this question: FLAG_ACTIVITY_NEW_TASK not behaving as expected when used in PendingIntent

    First, I changed this line:

    Intent notificationIntent = new Intent( this, MainActivity.class );
    

    To:

    Intent notificationIntent = new Intent( this, NotificationActivity.class );
    

    I made NotificationActivity.class a placeholder activity that will let other activities know when the app is being resumed from a notification. These lines of code were removed:

    notificationIntent.setAction( Intent.ACTION_MAIN );
    notificationIntent.addCategory( Intent.CATEGORY_LAUNCHER );
    notificationIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED );
    notificationIntent.putExtra( NotifyService.NOTIFICATION_INTENT, true );
    

    And, this line:

    PendingIntent contentIntent = PendingIntent.getActivity( this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT );
    

    Was changed to:

    PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT );
    

    In the onCreate() method of NotificationActivity, I added these lines to the bottom:

    STARTED_FROM_NOTIFICATION = true;
    finish();
    

    Where STARTED_FROM_NOTIFICATION is in a common source file. Then, in each activity in the onStart() method:

    if( STARTED_FROM_NOTIFICATION == true )
    {
        STARTED_FROM_NOTIFICATION = false;
        // Do something
    }
    

    I also removed android:launchMode="singleTop" from all activities.

    Using this method, the NotificationActivity will be placed on top of the existing stack of activities, but will be finished before it is displayed. After it is finished, onStart() for the activity below it will be called and operation works as desired.