Reputation: 1141
I am receiving messages from GCM.
This is how I handle receiving a message in my GCMBaseIntentService:
@Override
protected void onMessage(Context context, Intent intent) {
String msg = intent.getExtras().getString("message");
generateNotification(context, msg);
}
private static void generateNotification(Context context, String message) {
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, MyClass.class);
notificationIntent.putExtra("message", message);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults|= Notification.DEFAULT_LIGHTS;
notification.defaults|= Notification.DEFAULT_VIBRATE;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notificationManager.notify(0, notification);
}
In MyClass
I have this in onResume
:
String msg = this.getIntent().getStringExtra("message");
if(msg != null){
new AlertDialog.Builder(this)
.setTitle("New Notification")
.setMessage(msg)
.setNeutralButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).create().show();
}
The GCM message appears in the status bar. Once the notification is clicked, MyClass
opens and the AlertDialog
above appears.
I navigate away from MyClass
either by going to a new activity, clicking back or clicking home. When I return to that activity, the `AlertDialog' appears every single time I return.
How do I prevent this? I thought that the AlertDialog
would only appear once immediately after the notification in the status bar is clicked.
UPDATE:
So what I think is happening is that when I create a notification (generateNotification
) from a GCM message, it opens the activity with this new intent. Now every time this activity is opened, this same intent is re-used so the extras get read again and then the alert shows up. I still don't know how to stop this though.
I think I am going to try storing a SharedPreference
with the the intent's timestamp as an extra. Then I will only show the alert if msg == null
and the timestamp is new.
I like devunwired's answer, but in case anyone is curious, storing the timestamp in shared preferences worked as well.
This is how I implemented it: (in MyClass
I have this in onResume
)
String msg = this.getIntent().getStringExtra("message");
if(msg != null){
long newTime = intent.getLongExtra("intentTime", 0);
long oldTime = preferences.getLong("intentTime", 0);
if(newTime > oldTime){
new AlertDialog.Builder(this)
.setTitle("New Notification")
.setMessage(msg)
.setNeutralButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).create().show();
}
}
Upvotes: 1
Views: 3498
Reputation: 63293
You are correct that the Intent
is still attached to the Activity
so each entry into onResume()
will execute that code. It's not being re-used, necessarily, it's just that the Intent
you receive is always the one that started the instance, which doesn't change if you navigate to a new screen and back, or hit the HOME key because the current instance still exists (it is just stopped temporarily).
Strange that you say it happens with BACK as well. In the case of the BACK button, it should destroy the Activity
instance so a new launch would have a different Intent
associated with it. Unless the next time you launched it was from the same Notification or the recents menu (which will launch it with the previous Intent
as well).
You might try moving this logic into onCreate()
, where it will only get called when a new instance is being brought into play. Another option is to call setIntent()
on the Activity
after you have processed the incoming notification with a new blank Intent
so that subsequent entries do not launch that code.
Upvotes: 1