Posts tagged Push

GCM is Google’s new cloud messaging system, that is replacing C2DM.

Here is the bare bones, quick tutorial on how to get notifications working.

Register Application with Google

First go to Google’s API console. Setup a new project for your application.

Enable “Google Cloud Messaging for Android” service.

Click the “API Access” link and grab the API Key for later use.

Write the Client Side Code

In your AndroidManifest.xml you’ll need setup your configuration like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="fiserv.mobile.poc"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="15" />    
    <permission android:name="fiserv.mobile.poc.permission.C2D_MESSAGE" 
        android:protectionLevel="signature"/>    
    <uses-permission android:name="fiserv.mobile.poc.permission.C2D_MESSAGE" />     
    <!-- App receives GCM messages. -->
	<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
	<!-- GCM connects to Google Services. -->
	<uses-permission android:name="android.permission.INTERNET" /> 
	<!-- GCM requires a Google account. -->
	<uses-permission android:name="android.permission.GET_ACCOUNTS" />
	<!-- Keeps the processor from sleeping when a message is received. -->
	<uses-permission android:name="android.permission.WAKE_LOCK" />  
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>                
        <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" 
            android:permission="com.google.android.c2dm.permission.SEND" >
		  <intent-filter>
		    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
		    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
		    <category android:name="fiserv.mobile.poc" />
		  </intent-filter>
		</receiver>		
		<service android:name=".GCMIntentService" />
    </application>
</manifest>

Now develop an Intent Service, this is a service that will handle all aspects of communication with GCM. Just extend GCMBaseIntentService Here is why your Intent Service should look like:

 
package fiserv.mobile.poc;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;

public class GCMIntentService extends GCMBaseIntentService {

	@Override
	protected void onError(Context arg0, String arg1) {
		Log.e("Registration", "Got an error!");
		Log.e("Registration", arg0.toString() + arg1.toString());
	}

	@Override
	protected void onMessage(Context arg0, Intent arg1) {
		Log.i("Registration", "Got a message!");
		Log.i("Registration", arg0.toString() + " " + arg1.toString());
		// Note: this is where you would handle the message and do something in your app.		
	}

	@Override
	protected void onRegistered(Context arg0, String arg1) {
		Log.i("Registration", "Just registered!");
		Log.i("Registration", arg0.toString() + arg1.toString());	
		// This is where you need to call your server to record the device toekn and registration id.
	}

	@Override
	protected void onUnregistered(Context arg0, String arg1) {
	}
}

Finally in your Main Activity’s onCreate operation, call a method that looks like this:

    private void RegisterWithGCM()
    {    	 	
    	GCMRegistrar.checkDevice(this);
    	GCMRegistrar.checkManifest(this);
    	final String regId = GCMRegistrar.getRegistrationId(this);
    	if (regId.equals("")) {
    	  GCMRegistrar.register(this, SENDER_ID); // Note: get the sender id from configuration.
    	} else {
    		
    	  Log.v("Registration", "Already registered, regId: " + regId);
    	}
    }

Notice the SENDER_ID needs to come from configuration. You can get this value from the Google API Console. Just grab it off the end of your project URL.

Now fire up your app, it should register with GCM and print out your registration ID. You’ll want to copy that ID so you can send a test notification to your device.

You’ll want to record this registration id with your server, so you can start sending notifications from your server.

Send Notifications from Server

Here is a C# / .Net server example for sending notifications to GCM:

                using (var wc = new WebClient())
                {
                    wc.Headers.Add("Authorization", "key=" + serviceKey);
                    var nameValues = new NameValueCollection
                                         {
                                             {"registration_id", registrationId},
                                             {"collapse_key", Guid.NewGuid().ToString()},
                                             {"data.payload", HttpUtility.UrlEncode(message)}
                                         };
                    var resp = wc.UploadValues("https://android.googleapis.com/gcm/send", nameValues);
                    var respMessage = Encoding.Default.GetString(resp);
                    loggingServiceClient.Debug("Got respose from GCM: " + respMessage);
                }

This is just a simple example to show exactly how you send the message, I recommend using a framework like PushSharp when you implement this for real.

Notice the “serviceKey” variable in this example should be the value you got from Google API Console.

Once you send your message you should see log statements in your Android console or hit a breakpoint in your onMessage method of your Intent Service.

Note: make sure you are logged in with a Google account on you device, since that’s a requirement for GCM to work.


A great introduction to Mobile Push over the most common networks (Apple, Android, Windows, Blackberry) by Mike Willbanks.