Cloud Zone is brought to you in partnership with:

I'm Wolfram Rittmeyer, a software-developer from Germany. I have been developing with Java for a long time and have started developing Android applications in 2010. While developing I stumble upon pecularities or missing documentation as much as anyone else. This blog is where I dig into these issues and write down what helped me, what annoyed me and what I have learned. Wolfram is a DZone MVB and is not an employee of DZone and has posted 9 posts at DZone. You can read more from them at their website. View Full User Profile

Upstream Messages with Google Cloud Messaging

02.07.2014
| 5832 views |
  • submit to reddit

Google announced a new messaging model with Google Cloud Messaging on last years Google IO. This model allows for upstream messaging and for user specific notifications. This post is the first in a three-part series in which I am going to look into both these changes and to show you how to use them.

I had never written these posts if it weren’t for the Dutch Android User Group meetup in Utrecht (January 2014), where I had the pleasure to talk about this topic. This event was well-attended and was packed with interesting talks about the changes in Android 4.4 and Google Play Services. If you have ever the chance to attend a meetup of our Dutch colleagues, I strongly suggest to do so. It has been a gorgeous evening and was well worth the two-hour drive. It was not just the talks but also the overall atmosphere as well as the conversations during the breaks and afterwards. A big thanks to the organizers for the awesome evening!

You can find my slides on the speakerdeck site. And a video of the talk should also be available pretty soon.

Sample App

I have published sample apps on github where you can see how to use this in context. For the Android client clone the gcm_sample project. For the server clone the gcm_server project.

What’s new

With Google Play Services 3.1 Google made some changes to Google Cloud Messaging:

  • You can send messages upstream from the user’s device
  • You have to use a permanent connection between your backend and Google’s services
  • You can use user specific notifications

In this post I will only cover upstream messaging. That is the flow of events and what to do on Android’s side. In my next post I’m going to cover the server side – and in the third post I will write about user specific notifications. User notifications allow you to send user specific messages with the possibility to cancel notifications on other devices if they have been consumed already on one device.

Upstream messaging

With the new GCM release Google allows you to send messages directly back to Google’s cloud. That’s what they call upstream messaging. Have a look at the following diagrams. The first one is the traditional model of Google Cloud Messaging while the second one shows the new flow of events.

The classic communication flow with Google Cloud messaging

The classic communication flow with Google Cloud messaging

The communication model of Google Cloud Messaging with the new Cloud Connection Server

The communication model of Google Cloud Messaging with the new Cloud Connection Server

The first two steps in both diagrams are the same: You tell the Google Cloud Messaging API that you want to register a device (step 1). If the registration succeeds Google returns the registration id for this device (step 2).

Traditionally you would then send the registration id back to your server (step 3). The protocol was up to you but very likely HTTP. The server would (hopefully) respond with a success message (step 4).

From then on your server could send messages to Google’s Cloud Messaging service (step 5) and the user’s device would receive it, if it’s registration id was part of the registration_ids parameter of the message (step 6).

With upstream messaging though your app would send the registration id (step 3) not directly to your server, but instead call a method of the Google Play Services API. Google Play Services would then send the message to Google’s servers.

Google then processes the message and sends it to your backend. Obviously for this to work your backend must be connected in some way to Google’s cloud. I will deal with this part in my next post. For now it’s enough to know that there has to be a permanent connection between your backend and Google’s cloud and that Google will deliver messages that way (step 4).

After the registration id has been transmitted successfully you can send messages to the device (step 5). But with the new way to use Google Cloud Messaging you would use the existing connection between your server and Google’s servers and use a different protocol (with slightly different parameters).

Note that Google uses different names for its servers depending on which transmission model you want to use. Google uses the name “GCM HTTP Connection Server” for those servers receiving HTTP messages and it uses “GCM Cloud Connection Server” for those receiving XMPP messages via the permanent connection. The abbreviation CCS is very commonly used within GCM’s documentation.

Create your credentials

If you already use Google Cloud Messaging you can skip this part and proceed to the next section.

If you’re new to Google Cloud Messaging, you have to create an API key in Google’s Cloud Console/Google Developer Console. Do not confuse it with the Google Play Developer Console. Both are unrelated.

After logging in to the Cloud Console you will see a list of projects. Simply create a new one and give it a name and a project id in the next dialog. Now this could be a source of confusion. The project id you use here is not the project id you have to use in your code later on. It’s just a name which nevertheless has to be unique.

Afterwards creating the project the developer console will show you the project’s page. Go to “APIs & Auth” in the menu and turn on “Google Cloud Messaging for Android” in the huge list of Google’s services. Since Google displays all your active services at the top, the entry will move directly to the top after you enable it. Don’t be irritated by that tiny UX glitch. Simply scroll to the top and you will see that it’s status has changed to “On”. That’s great.

Switch to Credentials in the menu on the left. At the top of the new screen you can find a client id. It starts with a number followed by “.apps.googleusercontent.com”. Select the number (only the number), copy it and paste it into your strings.xml – or a special gcm_strings.xml that only contains the project id. Name the string whatever you like – in the sample project I expect a string named gcm_project_id.

That’s all you need for the Android part. But since you’re logged in to the dev console anyway, let me show you how to create the API key for your server right away.

Go back to the dev console. On the Credentials page there are two sections. The OAuth section on the top is where you have found the project id. Below of it is the section called “Public API access”. It’s still empty. Click “Create New Key” and in the next dialog select “Server key”. Afterwards you will see the API key for server applications together with some additional information. You will use the API key when following my next post about the server side of GCM.

Sign up for using the new features

To be able to use all the shiny new features of Google Cloud Messaging, you have to sign up first. With the sign up form you “Sign up to be a trial partner”. The new services are not yet finalized. It’s a bit like it has been with Google Cloud to Device Messaging (C2DM) – the predecessor to GCM. You had to sign up as well, and when the service was finally made public, it had evolved to Google Cloud Messaging. So expect the API to change!

Using Google Play Services

You need to use Google Play Services from within your app for registering the device for as well as for sending upstream messages.

Setting up Google Play Services is easy, but requires too many steps to cover them in this post. And those steps also are different depending on whether you use Android Studio, Eclipse or something else. Have a look at the Play services documentation if it’s the first time you use Google Play Services.

The very first step in your code when using Google Play Services is to make sure that Google Play Services are available at all. You can do so with the following snippet:

	private boolean checkPlayServices() {
	   int resultCode =
	         GooglePlayServicesUtil
	            .isGooglePlayServicesAvailable(getActivity());
	   if (resultCode != ConnectionResult.SUCCESS) {
	      if (GooglePlayServicesUtil.
	            isUserRecoverableError(resultCode)) {
	         GooglePlayServicesUtil.getErrorDialog(
	               resultCode,
	               getActivity(),
	               RC_RES_REQUEST).show();
	      } else {
	         Log.i("grokkingandroid",
	               "This device is not supported.");
	      }
	      return false;
	   }
	   return true;
	}

What to do when the services are not available, depends on how important they are for your app. If Play Services are not essential, I suggest to let the user know – but in an unobtrusive way. After all the app is usable without it, so do not annoy your users with dialogs or other stuff that keeps them from doing what they actually installed the app for.

Registering the device for Google Cloud Messaging

The next step is to register the device. Google needs to know about your device before your app is allowed to receive or send messages.

In my sample app the user has to explicitly click the button register. Not a typical use case, but for the sample this makes sense. Now when to do this is in a real app is up to you. But when your app benefits from Google Cloud Messaging you usually want to register the device as soon as possible.

I also let the user select a Google account. Your app’s users do not need one for Google Cloud Messaging. I solely request one to use this account for user specific notifications. I will cover those in the third post of this series.

Registering actually is very easy. First get hold of a GoogleCloudMessaging object and then simply call its method register() passing in the project id of the dev console (see “Create your credentials” above):

String projectId = 
      getResources().getString(R.string.gcm_project_id);
GoogleCloudMessaging gcm = 
      GoogleCloudMessaging.getInstance(this);
String regid = gcm.register(projectId);

Be careful though: Asking for the registration id is a blocking request. Hence, you should always use the call in a separate thread off the main thread (UI thread). In the sample project I am using an IntentService to achieve this.

Send messages upstream

As soon as the device is registered, it can send messages upstream – as well as receive messages. Probably the very first message to send upstream is the newly received registration id.

Sending messages is nearly as simple as registering. You create a Bundle with all the payload data you want to transmit and you also have to create a unique message id. In my sample code I simply increase a counter I keep within the SharedPreferences for the message id. Depending on your payload the code might look more or less like this:

try {
   Bundle data = new Bundle();
   // the account is used for keeping 
   // track of user notifications
   data.putString("account", account);
   // the action is used to distinguish 
   // different message types on the server
   data.putString("action", Constants.ACTION_REGISTER);
   String msgId = Integer.toString(getNextMsgId());
   gcm.send(projectId + "@gcm.googleapis.com", msgId,
         Constants.GCM_DEFAULT_TTL, data);
} catch (IOException e) {
   Log.e("grokkingandroid",
         "IOException while sending registration id", e);
}

As you can see you once again need a GoogleClientMessaging object and call its send() message.

This message takes as parameters the project id appended with the fixed string “@gcm.googleapis.com“, a unique message id, a time to live value and the bundle with your payload.

You might notice that I do not include the registration id as part of the payload. That’s because Google Play Services adds the registration id to every message to your backend anyway. You will see in the next post which parameter Google uses for the registration id. For now, just keep in mind that above code is all that is actually needed.

Those strings within the bundle are not even necessary. I use the account because I want to send user specific messages and I use the action to differentiate on my server between different message types.

As you can see there is no special message for sending the registration id back home. It’s just a message like any other upstream message.

Published at DZone with permission of Wolfram Rittmeyer, author and DZone MVB. (source)

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