Saturday, July 9, 2011

C2DM – A 10 minutes recipe

If you are interested in a quick overview and some code examples, keep reading.

Android Cloud to Device Messaging (C2DM) is a lightweight framework enabling the device to refresh its data from the server using “push” messages.Instead the device will go to the server periodically, looking for new data, spending precious battery time, the server (which hold the state of the data) simply sends a lightweight message to the device, telling him “dude, I got some new fresh data ready for you, come get it”.

Life cycle:

The device sends a registration request to a C2DM server, and gets back a registration ID.

The device sends that ID to the application server.

The application server sends an authentication request to a C2DM server, and gets back a ClientLogin authorization token.

The application server use the authorization token and the registration Id he got from the device, and sends a message to a C2DM server.

The C2DM server sends the message to the specific device with the given registration ID. (There’s an option to tell the C2DM server to wait if the device is idle, and also to use a collapse key to prevent flooding the device with similar messages).

* The application on the device doesn’t need to be running to get a message. The C2DM server will wake it up.

Before writing any code, you need to freely sign up to the C2DM service from the signup page.

Now, let's get our hands dirty.

- On theAndroid side -

If you test the following example on the emulator make sure that you use Google API 8 or later. You also have to register a Google user on the virtual device under "Settings" –> "Accounts Sync".

If you test the following example on a real device make sure that the Android Market is installed.

Lines need to be added to AndroidManifest.xml:

<manifestpackage="com.example.myapp" ...>

<!-- Only this application can receive the messages and registration result -->

Now, add a package: com.google.android.c2dm and put there the following files: C2DMBaseReceiver, C2DMBroadcastReceiver, C2DMessaging. (You can find them in the Chrome to Phone example here, under trunk –> android –> c2dm)

Create a class named C2DMReceiver in your root package (com.example.myapp).

publicclass C2DMReceiver extends C2DMBaseReceiver

{

public C2DMReceiver()

{

super("sender.adress@gamil.com");

}

@Override

publicvoid onRegistered(Context context, String registrationId)

{

Log.v("C2DMReceiver-onRegistered", registrationId);

// send registration id and service/acct name to http server

}

@Override

publicvoid onUnregistered(Context context)

{

Log.v("C2DMReceiver-onUnregistered", "got here!");

}

@Override

publicvoid onError(Context context, String errorId)

{

Log.v("C2DMReceiver-onError", errorId);

}

@Override

protectedvoid onMessage(Context context, Intent intent)

{

Log.i("GenericNotifier", "onMessage called");

Bundle extras = intent.getExtras();

String message = (String)extras.get("payload");

if(message != null)

{

Log.i("Message is ", message);

Log.i("GenericNotifier", message);

}

}

}

Add this code to your activity, where you want to register your device to the C2DM service:

publicvoid registerMyAccount()

{

String registrationId = C2DMessaging.getRegistrationId(this);

if(registrationId == null || registrationId.equals(""))

{

C2DMessaging.register(this, C2DMConfig.C2DM_SENDER);

}

else

{

// If you don't save the registration ID in the server,

// and the device is already registered,

// you can send the registration Id again here

}

}

- On theServer side -

Here, you do two things:

Get authentication token from a Google server.

Send a message to a specific device with the registration ID you got from that device.

You can implement the server side however you like, here is a simple implementation: