Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

singleTask and singleInstance not respected when using PendingIntent?

I have an activity with launchMode set to singleTask:

<activity
    android:name="com.blah.blah.MyActivity"
    android:launchMode="singleTask">
</activity>

I have an ongoing notification with a PendingIntent that launches that activity:

Intent activityIntent = new Intent( this,
                                    MyActivity.class );
TaskStackBuilder stackBuilder = TaskStackBuilder.create( this );
stackBuilder.addParentStack( MyActivity.class );
stackBuilder.addNextIntent( activityIntent );
PendingIntent resultingActivityPendingIntent = stackBuilder.getPendingIntent( REQUEST_CODE,
                                                                              PendingIntent.FLAG_UPDATE_CURRENT );
...
m_notificationBuilder.setContentIntent( resultingActivityPendingIntent );
startForeground( ONGOING_NOTIFICATION_ID,
                 m_notificationBuilder.build() );

When I am interacting with an existing MyActivity, then I hit Home and restart MyActivity via the launcher, MyActivity's onNewIntent() gets called as expected.

The problem is that when I am interacting with an existing MyActivity, and I click on the ongoing notification, a new MyActivity is created via onCreate(), and the existing one is destroyed via onDestroy(). I expected that MyActivity's onNewIntent() would be called instead. Why doesn't this happen?

I have tried these answers without success:

  • Intent - if activity is running, bring it to front, else start a new one (from notification)
  • How to make notification resume and not recreate activity?
  • FLAG_ACTIVITY_REORDER_TO_FRONT ignored (in this case the existing instance is not destroyed when the notification is clicked)
like image 249
Kevin Avatar asked Feb 12 '23 00:02

Kevin


1 Answers

Your problem is due to the use of TaskStackBuilder. This code is causing your problem:

Intent activityIntent = new Intent( this,
                                MyActivity.class );
TaskStackBuilder stackBuilder = TaskStackBuilder.create( this );
stackBuilder.addParentStack( MyActivity.class );
stackBuilder.addNextIntent( activityIntent );
PendingIntent resultingActivityPendingIntent =
         stackBuilder.getPendingIntent(REQUEST_CODE,
         PendingIntent.FLAG_UPDATE_CURRENT );

When you use TaskStackBuilder this way, it sets additional flags in the generated Intents that cause the task to be reset (all Activities in the task are destroyed) before your Activity gets launched.

Instead use:

Intent activityIntent = new Intent( this,
                                MyActivity.class );
PendingIntent resultingActivityPendingIntent =
         PendingIntent.getActivity(this, REQUEST_CODE,
             activityIntent, PendingIntent.FLAG_UPDATE_CURRENT );
like image 78
David Wasser Avatar answered Feb 15 '23 11:02

David Wasser