Notification click: activity already open

AndroidNotificationsAndroid Activity

Android Problem Overview


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!

Android Solutions


Solution 1 - Android

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 - Android

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 - Android

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 - Android

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 - Android

I think you should add some logic to make it work, maybe this can help:

For example I have a Splash Screen (Launcher and MAIN) of APP:

public class SplashScreen extends AppCompatActivity {
    private final int TIME_OUT = 2000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash_screen);

        // Suscribirse al tema Notificaciones
        FirebaseMessaging.getInstance().subscribeToTopic("NOTA");
        if (getIntent().getExtras() != null) {
            if (getIntent().getExtras().size()>1){
                Intent home_activity = new Intent(getApplicationContext(), Home.class);
                home_activity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                if (getIntent().getExtras() != null) {
                    for (String key : getIntent().getExtras().keySet()) {
                        String value = "" + getIntent().getExtras().getString(key);
                        Log.d("TAG", key + "=" + value);
                        switch (key) {
                            case "url":
                                home_activity.putExtra("url", value);
                                break;
                        }
                    }
                }
                startActivity(home_activity);
                finish();

            }else{
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Intent home_activity = new Intent(getApplicationContext(), Home.class);
                            home_activity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(home_activity);
                            finish();
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                }, TIME_OUT);
            }


        } else {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    try {
                        Intent home_activity = new Intent(getApplicationContext(), Home.class);
                        home_activity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        startActivity(home_activity);
                        finish();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }, TIME_OUT);
        }

    }

}

And in my FirebaseService I have done the following:

public class FCMessagingService extends FirebaseMessagingService {

    private final String TAG = "PUSH";
    private String body = "";
    private static String _url = "";
    private static int numMessage = 0;

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        String from = remoteMessage.getFrom();
        Log.d(TAG, "Mensaje recibido de: " + from);

        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Notificación: " + remoteMessage.getNotification().getBody());

            if (remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Data: " + remoteMessage.getData());
                try {
                    JSONObject data = new JSONObject(remoteMessage.getData());
                    String url = data.getString("url");
                    Log.d(TAG, "onMessageReceived: \n" + "Extra Information: " + url);
                    this._url = url;
                    Log.d("_URL",_url);
                    mostrarNotificacion(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
                    mensaje(url, remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }



    }


    private void mensaje(String url, String title, String body){
        boolean acti =  Util.comprobarActivityALaVista(getApplicationContext(), "com.dev.android.subagan.MainActivity");
        if(acti){

            Intent imain = new Intent(MainActivity.URL);

            imain.putExtra("key_url",url);
            imain.putExtra("key_title",title);
            imain.putExtra("key_body",body);

            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(imain);

        }else{

            Intent ihome = new Intent(Home.URL);

            ihome.putExtra("key_url",url);
            ihome.putExtra("key_title",title);
            ihome.putExtra("key_body",body);
            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(ihome);

        }

    }




    private void mostrarNotificacion(String title, String body) {

        final int NOTIFICATION_ID = 3000;

        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra("url",_url);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT  );



        Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(title)
                .setContentText(body)
                .setAutoCancel(true)
                .setSound(soundUri)
                .setTicker(body)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notificationBuilder.build());

    }

}

Solution 6 - Android

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPX DeveloperView Question on Stackoverflow
Solution 1 - AndroiddevunwiredView Answer on Stackoverflow
Solution 2 - AndroidquietmintView Answer on Stackoverflow
Solution 3 - AndroidAfjalur Rahman RanaView Answer on Stackoverflow
Solution 4 - Androiduser4356416View Answer on Stackoverflow
Solution 5 - AndroidCarlos Alberto GonzalezView Answer on Stackoverflow
Solution 6 - AndroidManjunathView Answer on Stackoverflow