Cloud Zone is brought to you in partnership with:

Senior Software Engineer & Architect. I have programmed with a variety of languages. Originally:C/C++, Mostly: Java, Occasionally: PHP, VB, Python, Unix Shell, JavaScript, Mainframe EasyTrieve and JCL. I also do Android development at the present time. Tony is a DZone MVB and is not an employee of DZone and has posted 36 posts at DZone. You can read more from them at their website. View Full User Profile

Google Cloud Messaging: Collapsible Messages

08.21.2012
| 11021 views |
  • submit to reddit

In a previous article, we looked at how to set up Google Cloud Messaging (GCM) in Android applications. We learned that GCM is a free service that allows us to push messages from the cloud to a number of mobile recipients running our Android application and registered with our service.

The push messages can be either collapsible or non-collapsible. "Collapsible" means that the most recent message overwrites any previous ones queued for sending. A typical example of collapsible messaging is a live game score. In case previous score updates haven't reached their destination yet, the Android clients would only get the latest one. This happens however on a best effort basis: the order in which messages get sent in GCM is not guaranteed, so in some cases the "latest" message may not be actually the most recent one.

 

Take a Baseball game between the Boston Red Sox and the New York Yankees as an example. Here's how we would construct a collapsible update to send to devices registered with our sports push notification service. All code samples here are slight modifications of the GCM Demo application . As commented in the previous article, the reader is invited to download the Demo (both client and server) and experiment. The Demo uses the GCM helper library for Java that abstracts much of the low-level stuff (like handling messages in JSON format).

However, while being pretty useful for introducing GCM, the Demo doesn't actually handle push content. It only fires & acknowledges the event, while the same notification (set up in the client's configuration) is used in all cases ("From GCM: you got message!"). So let's write some actual message sending & receiving code:

Server Code

// in imports
import com.google.android.gcm.server.Message;

// Inside send method, construct a collapsible message
Message message = new Message.Builder()
  .collapseKey("Fenway Park Game") // The key for all updates.
  .timeToLive(600) // Time in seconds to keep message queued if device offline.
  .delayWhileIdle(true) // Wait for device to become active before sending.
  .addData("team1", "Red Sox:1")
  .addData("team2", "Yankees:0")
  .build();
// send in chunks of 1,000 devices
//...

It's worth noting that a given GCM message can be sent to up to 1,000 mobile clients at a time. In case our user base is larger than that, we'll need to break the message sending process in chunks of 1,000 recipients. One way to do that would be to use a java.util.concurrent.Executor thread pool and send the chunks asynchronously, as does the GCM Demo server.

Client Code

Now we need to process the GCM message in our Android application:

// inside GCMIntentService
@Override
protected void onMessage(Context context, Intent intent) {

    String message = intent.getStringExtra("collapse_key")  + "\n"
                     + intent.getStringExtra("team1") + " "
                     + intent.getStringExtra("team2");

    displayMessage(context, message);
    // notify user
    generateNotification(context, message);
}

Notice how a collapse_key is set up by the server and retrieved by the client. That key is how GCM identifies the flow of collapsible updates for a given event. In case there are several push notifications queued for sending with the same collapse key "Fenway Park Game", only the most recent one will be delivered.

Here's how a the push notification above looks like on an actual Android device. The last screen is the opened GCMClient application turned into a "Sports Center" for demonstration purposes:

We can see why collapsible push makes sense here: let's suppose we were using non-collapsible messages and the score was updated say 4 more times during the game. Let's imagine a common occurrence where some of our users didn't get the first notifications and became reachable again right after the latest score. Then they would get all five messages instead of just the last one. All the messages except the most recent one would be useless and we would have over-notified those clients. That wouldn't be very smart. We want our application to be useful, not annoying. As mentioned, collapsible messages are not guaranteed to get to their destinations in order, but they still allow us to use GCM intelligently and refrain from being too...pushy.

From Tony's Blog

Published at DZone with permission of Tony Siciliani, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)