The question:
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!
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 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
.
Method 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().
Method 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.
Method 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.
Method 5
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());
}
}
Method 6
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, new Random().nextInt(), intent, 0);
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0