Ryan
Ryan

Reputation: 1141

AlertDialog After GCM Message Shows Up Every Time The App Is Opened

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

Answers (1)

devunwired
devunwired

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

Related Questions