Question

I'm trying to implement a GCM client & server architecture. Everything works fine so far.

Except: When my activity is closed and I get a new notification by GCM, the notification is displayed in the notification bar. So far, so good. But when I click on the notification, my activity is opened but the onReceive event of my BroadcastReceiver is not triggered. :( If the Activity is open, the onReceive is triggered perfectly.

Do you know, what's wrong here?

Cheers

Chris

So this is my service:

package xy;

import ...;

public class GcmIntentService extends IntentService
{
  private NotificationManager mNotificationManager;
  NotificationCompat.Builder builder;


  public GcmIntentService()
  {
    super("GcmIntentService");
  }


  @Override
  protected void onHandleIntent(Intent intent)
  {
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    String messageType = gcm.getMessageType(intent);

    if (!extras.isEmpty()) { // has effect of unparcelling Bundle

     final int notificationID = (int) (Math.random() * 100000000);

     if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
        sendNotification("GCM notification: Send error", extras.toString(), notificationID);
     } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
       sendNotification("Deleted messages on server", extras.toString(), notificationID);
      // If it's a regular GCM message, do some work.
      } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
       sendNotification(extras.getString(Utils.TICKER_TITLE_MESSAGE_KEY), extras
            .getString(Utils.TICKER_TEXT_MESSAGE_KEY), notificationID);
        Intent intentToBroadCast = new Intent(Utils.DISPLAY_MESSAGE_ACTION);
        intentToBroadCast.putExtra(Utils.MESSAGE_EXTRA_BUNDLE_KEY, extras);
        intentToBroadCast.putExtra(Utils.NOTIFICATION_ID_KEY, notificationID);
        sendBroadcast(intentToBroadCast);
      }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    GcmBroadcastReceiver.completeWakefulIntent(intent);
  }


  private void sendNotification(final String aTitle, final String aText, final int aNotificationID)
  {
    mNotificationManager = (NotificationManager) this
        .getSystemService(Context.NOTIFICATION_SERVICE);

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this,
        DemoActivity.class), 0);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(
        R.drawable.ic_stat_gcm).setContentTitle(aTitle).setStyle(
        new NotificationCompat.BigTextStyle().bigText(aText)).setContentText(aText);

    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(aNotificationID, mBuilder.build());
  }
}

And here's the Receiver in my activity, which is to display the incoming message:

public class GcmResultReceiver extends BroadcastReceiver
{
  @Override
  public void onReceive(Context context, Intent intent)
  {
    Bundle extras = intent.getBundleExtra(Utils.MESSAGE_EXTRA_BUNDLE_KEY);
    String s = extras.getString(Utils.CONTENT_TITLE_MESSAGE_KEY) + "\n"
        + extras.getString(Utils.CONTENT_TEXT_MESSAGE_KEY);
    mDisplay.setText(s);

    int notificationID = intent.getIntExtra(Utils.NOTIFICATION_ID_KEY, -1);
    if (-1 != notificationID) m_SentNotificationIDs.add(notificationID);

    if (m_IsVisible) {
      clearNotifications();
    }
  }
};

Everything was copied and adapted from the GCM example from the Google Android tutorial.

Was it helpful?

Solution

The BroadcastReceiver is triggered before the notification is displayed in the notification bar. It contains the code that displays the notification and opens the activity when it is tapped (unless it is starting an intent service that does that work).

Therefore, if you see the notification, it means the BroadcastReceiver was triggered.

You don't need an additional BroadcastReceiver for passing the notification data from the first receiver to your app. If you wish to pass the notification data to the Activity that is being launched when the notification is tapped, you can pass it to the intent used to launch that activity.

Suppose you change your sendNotification call to:

sendNotification(extras, notificationID);

Then you can implement it like this:

  private void sendNotification(Bundle extras, final int aNotificationID)
  {
    mNotificationManager = (NotificationManager) this
        .getSystemService(Context.NOTIFICATION_SERVICE);

    Intent demoIntent = new Intent(this, DemoActivity.class);
    demoIntent.putExtras (extras);
    demoIntent.putExtra (Utils.NOTIFICATION_ID_KEY, notificationID);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, demoIntent, 0);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(
        R.drawable.ic_stat_gcm).setContentTitle(extras.getString(Utils.TICKER_TITLE_MESSAGE_KEY)).setStyle(
        new NotificationCompat.BigTextStyle().bigText(extras.getString(Utils.TICKER_TEXT_MESSAGE_KEY))).setContentText(extras.getString(Utils.TICKER_TEXT_MESSAGE_KEY));

    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(aNotificationID, mBuilder.build());
  }

This way your DemoActivity will get the notification id and all the extras holding the data of the notification. You can access them in your activity's onCreate (or perhaps it would be better to do it in onResume, in case your Activity is already started).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top