Sending and Receiving Android Push Notifications w/ GCM | PubNub
original source : https://www.pubnub.com/blog/2015-06-24-sending-receiving-android-push-notifications-with-gcm-google-cloud-messaging/
When developing mobile applications for smart phones and tablets, there is no “one size fits all” solution for realtime data propagation. This is because each mobile operating system provides its own solution for native application push notifications.
In iOS, this mechanism is APNs, or Apple Push Notification Service. In Android, the mechanism for native applications is Google Cloud Messaging (GCM) notifications.
To clarify the use cases a bit: when an app is in the foreground, PubNub’s channels will do a great job for providing realtime data streams. The tricky case happens when the app is in the background, when the user has its phone locked, and especially when the user doesn’t have access to an internet connection via WiFi or LTE.
To cope with these tricky cases, the easiest solution is mobile push notifications. Google provides an amazing service called Google Cloud Messaging, which we described in our Android push notifications with GCM overview.

If your application is destined for multiple platforms, the PubNub SDK makes your life easier by supporting APNs and GCM out of the box. Even if you don’t support multiple platforms yet, using the PubNub support for GCM will streamline your code by using a single set of libraries for PubNub Data Streams as well as GCM notifications.
Getting Started
If you took a look at the end of our previous article, you have all the necessary information to get your developing environment setup: getting the proper API Keys, getting the right dependencies, etc. Make sure you have Google Play Services available.

Our App
We are going to take a look at the basic blocks of code you’ll need to make your own application with GCM-enabled. For this reason, we will keep the code minimal, with a very basic user interface. This article will only review the key elements of the code.
Our application is going to receive GCM Mobile Push Notifications and send them over PubNub.
The most important element here is that we want our app to receive these notifications even if the app is not on the foreground: it must be able to work even if the screen is off and the phone is locked.
To do so we will need 3 classes:
- An Activity which controls the view. We will be able to register, unregister and send push notifications from this screen.
- A Service which will receive the GCM message and show it to the user as a notification, regardless of if our app is on the foreground.
- A Broadcast Receiver. This class will need to be registered in the manifest. Its role is to listen for system events for example. In our case it will be listening for received GCM messages. The receiver will open s partial wake lock to allow the CPU to run our Service even if the screen is off. We must release the wake lock as soon as our service is done.
Ready? Let’s roll. Create a new project with the usual hello-world activity, get the dependencies and we are good to go.
Manifest
Let’s start with our manifest. We’ll want to add some permissions under the manifest markup.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <permission android:name="your.package.name.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="your.package.name.permission.C2D_MESSAGE" />
Next step is to register our Broadcast Receiver and Service. You should already have that last line in your manifest if you added the google play services properly.
<receiver android:name=".GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="your.package.name" /> </intent-filter> </receiver> <service android:name=".GcmIntentService" /> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
Broadcast Receiver
We are going to start by creating a new class which extends WakefulBroadcastReceiver.
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ComponentName comp = new ComponentName(context.getPackageName(), GcmIntentService.class.getName()); startWakefulService(context, (intent.setComponent(comp))); setResultCode(Activity.RESULT_OK); } }
This is fairly simple code. When the broadcast receiver receives the event, the overridden method is called. It launches our service.
However, note that we did not use a BroadcastReceiver but a WakefulBroadcastReceiver. This simplifies our task: we a normal broadcast receiver, we would need to wake up the CPU if the screen is off, launch the service and put the phone back to sleep. This requires manipulating the Android PowerManager and WakeLock. The WakefulBroadcastReceiver takes care of all that for us. Pretty neat.
The Service
A broadcast receiver by design cannot execute long tasks. It must call other classes to do its work. We need to create a new class. We cannot start a new activity because we do not want the user to be forced to switch to our app. Instead we use a service. It will be able to execute tasks in the background.
public class GcmIntentService extends IntentService { 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() && GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { sendNotification("Received: " + extras.toString()); } GcmBroadcastReceiver.completeWakefulIntent(intent); }
We decided to keep it simple. The message content is included in the intent extras. There are various message types, in this code we are only considering the most common case which will probably a message of type message. We extract its content and feed it to a method which creates the notification to the user.
The last line releases the wake lock which was provided by our WakefulBroadcastReceiver.
private void sendNotification(String msg) { NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("PubNub GCM Notification") .setStyle(new NotificationCompat.BigTextStyle() .bigText(msg)) .setContentText(msg); mBuilder.setContentIntent(contentIntent); mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); }
This is fairly classic code to create a notification which redirects to our main activity when clicked on.
This is pretty good!
So far we have a receiver which waits for “received GCM message” events and starts a partial wake lock for our service to generate the notification. Once the notification is created, we release the wake lock.
Now our next step is to register our app to the Google Cloud Messaging service!
Main Activity
We are not get into the details of the user interface and the code wiring the buttons, feel free to make your own UI/UX. The code samples are just guides to create your own app. This is what our very basic and sober UI looks like:

Our code so far receives the notifications, but we do need to tell Google Cloud Messaging which device should receive these notifications. This step is called registering the app.
We need to send the “sender id” to the GCM servers. This sender id is your project’s number which is available on the google developer’s console. If you followed our GCM notification overview, you should be all set.
When we register an app, we will receive a registration ID which we must store. We decided to store it in the shared preferences. Our code follows several steps:
- Check if Google Play Services are available – If not, abort.
- Check if we are already registered. If so, abort.
- Register to GCM and receive our registration ID.
- Store our registration ID.
Registration
Note, regId is a class variable.
private void register() { if (checkPlayServices()) { gcm = GoogleCloudMessaging.getInstance(this); try { regId = getRegistrationId(context); } catch (Exception e) { e.printStackTrace(); } if (regId.isEmpty()) { registerInBackground(); } else { toastUser("Registration ID already exists: " + regId); } } else { Log.e(TAG, "No valid Google Play Services APK found."); } }
We start our registration process by checking it Google Play Services are available -we will look into that part of the code in a second. If they are, another piece of our code will retrieve that data from the shared preferences. If we return an empty string, we aren’t registered and need to register in the background, off of the main thread.
Checking Google Services
private boolean checkPlayServices() { int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.SUCCESS) { if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) { GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show(); } else { Log.e(TAG, "This device is not supported."); finish(); } return false; } return true; }
The code is fairly self explanatory.
Fetching the Registration Id
private String getRegistrationId(Context context) throws Exception { final SharedPreferences prefs = getSharedPreferences(MainActivity.class.getSimpleName(), Context.MODE_PRIVATE); String registrationId = prefs.getString(PROPERTY_REG_ID, ""); if (registrationId.isEmpty()) { return ""; } return registrationId; }
We look for the registration ID in the shared preferences. If they are not available, we return an empty string.
Requesting The Registration Id
private void registerInBackground() { new AsyncTask() { @Override protected String doInBackground(Object[] params) { String msg; try { if (gcm == null) { gcm = GoogleCloudMessaging.getInstance(context); } regId = gcm.register(SENDER_ID); msg = "Device registered, registration ID: " + regId; sendRegistrationId(regId); storeRegistrationId(context, regId); Log.i(TAG, msg); } catch (Exception ex) { msg = "Error :" + ex.getMessage(); Log.e(TAG, msg); } return msg; } }.execute(null, null, null); }
This task may take longer time and needs to be executed off of the main thread. Most of the code is straightforward. We are calling 2 methods which we will describe in a second. Not that we are registering with the SENDER_ID which was provided by the google console.
Our next step is to send the registration Id to PubNub!