Notification click: activity already open

I have an application with notifications that open a certain activity if I click them. I want that, if I click the notification and the activity is already opened, it's not started again, but just brought to front.

I thought I could do it with the flag FLAG_ACTIVITY_BROUGHT_TO_FRONT or FLAG_ACTIVITY_REORDER_TO_FRONT, but it keeps opening it again so I have the activity twice.

This is my code:

event_notification = new Notification(R.drawable.icon,
            mContext.getString(R.string.event_notif_message), System.currentTimeMillis()); 
Intent notificationIntent = new Intent(mContext, EventListActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
sendNotification(event_notification, notificationIntent, mContext.getString(R.string.event_notif_title),
                body, Utils.PA_NOTIFICATIONS_ID);

Can I manage it with flags or should I store a variable in SharedPreferences to check if it's opened or not?

Thanks!


Solution 1:

You need to set the launchMode attribute of the Activity you are starting to singleTop. This will cause incoming Intents to be delivered to the existing instance rather than starting a new instance when that Activity is already at the top of the task's stack.

This is done in the manifest by adding android:launchMode="singleTop" to the <activity> element. To access the latest Intent (if you are interested in any data that may have passed in with it), override onNewIntent() in your Activity.

Solution 2:

Try setting the flags to Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP instead.

From the documentation for FLAG_ACTIVITY_CLEAR_TOP (emphasis mine):

If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.

For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.

The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to the current instance's onNewIntent().

Solution 3:

Use onNewIntent() for handling new data from notification click and refresh the activity.

In onNewIntent get the new data from the new intent(which served by the new notification) and catch them, for example:

title = intent.getStringExtra("title")

in onCreate previously :)

It will refresh present activity with new notification data.

You can also follow this tutorial.

Solution 4:

Notification.Builder mBuilder =
            new Notification.Builder(this)
            .setSmallIcon(R.drawable.cmplayer)
            .setContentTitle("CoderoMusicPlayer")
            .setContentText("PLayer0!");

    Intent resultIntent = new Intent(this, 

    AndroidBuildingMusicPlayerActivity.class);
        resultIntent.setAction(Intent.ACTION_MAIN);
        resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                resultIntent, 0);

        mBuilder.setContentIntent(pendingIntent);
        NotificationManager mNotificationManager =
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mNotificationManager.notify(1, mBuilder.build());

Just Copy the code and paste it in your main launcher activity.

Here is Original Answer

Solution 5:

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, new Random().nextInt(), intent, 0);