Thursday, August 30, 2012

Google Cloud Messaging (GCM)


Google Cloud Messaging (GCM)

GCM Application


Google Cloud Messaging for Android (GCM) is a service that helps developers send data from servers to their Android applications on Android devices. The service provides a simple, lightweight mechanism that servers can use to tell mobile applications to contact the server directly, to fetch updated application or user data. The GCM service handles all aspects of queuing of messages and delivery to the target Android application running on the target device.
The Google Cloud Messaging (GCM) is to use the Google Cloud Messaging framework in your Android application. You will get configuration and setting up GCM in Android.

DCM consists of two part –
1.       A web server containing a page where you can send messages
2.       An Android application that receives and displays such messages.

Details information about API reference documentation  are available here –



Requirements

For the web server:
  • Ant 1.8 (it might work with earlier versions, but it's not guaranteed).
  • One of the following:
  • A Google account registered to use GCM.
  • The API key for that account.
For the Android application:
  • Emulator (or device) running Android 2.2 with Google APIs.
  • The Google API project ID of the account registered to use GCM.

Setting Up GCM


Before proceeding with the server and client setup, it's necessary to register a Google account with the Google API Console, enable Google Cloud Messaging in GCM, and obtain an API key from the Google API Console.
Create a Google APIs Project




Fig Source – Images from developer.android.com
3.       Note: If you already have existing projects, the first page you see will be the Dashboard page. From there you can create a new project by opening the project drop-down menu (upper left corner) and choosing Other projects > Create.
4.       Click Create project. Your browser URL will change to something like:
5.       Take note of the value after #project: (753945026852in this example). This is your project ID, and it will be used later on as the GCM sender ID.

Enabling the GCM Service
Ø  In the main Google APIs Console page, select Services.
Ø  Turn the Google Cloud Messaging toggle to ON.
Ø  In the Terms of Service page, accept the terms.



Obtaining an API Key


1.       In the main Google APIs Console page, select API Access. You will see a screen that resembles the following




2.       Click Create new Server key. Either a server key or a browser key should work. The advantage to using a server key is that it allows you to whitelist IP addresses. The following screen appears:



3.       Click Create:

Key for server apps (with IP locking)
API key:
AIzaSyBRuekUkXORED8AcNh9rGHbPs7Meho1gxC
IPs:
Any IP allowed
Activated on:
Aug 30, 2012 2:40 AM
Activated by:
Rkjhaw1983@gmail.com




Key for browser apps (with referers)
API key:
AIzaSyCFF4ZVTF4ULrBXBQMhG2gUxsK6apqez4q
Referers:
Any referer allowed
Activated on:
Aug 30, 2012 2:30 AM
Activated by:
rkjhaw1983@gmail.com


Install the Helper Libraries



  •         To perform the steps described in the following sections, you must first install the helper libraries (reference: client and server).
  •          From the SDK Manager, install Extras > Google Cloud Messaging for Android Library.
  •       This creates a gcm directory under YOUR_SDK_ROOT/extras/google/
  •         containing these subdirectories: gcm-client,gcm-serversamples/gcm-demo-clientsamples/gcm-demo-server, and samples/gcm-demo-appengine.
Note: If you don't see Extras > Google Cloud Messaging for Android Library in the SDK Manager, make sure you are running version 20 or higher. Be sure to restart the SDK Manager after updating it.

Writing the Android Application


Step 1: Copy the gcm.jar file into your application classpath
To write your Android application, first copy the gcm.jar file from the SDK's gcm-client/dist directory to your application classpath.
Step 2: Make the following changes in the application's Android manifest
1.       GCM requires Android 2.2 or later, so if your application cannot work without GCM, add the following line, where xx is the latest target SDK version:
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="xx"/>

                 Declare and use a custom permission so only this application can receive GCM messages

<permission android:name="my_app_package.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="my_app_package.permission.C2D_MESSAGE" /> 

             Add the following permissions:


<!-- 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" />

        Add the following broadcast receiver:

<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="my_app_package" />
  </intent-filter>
</receiver>


  •    This broadcast receiver is responsible for handling the 2 intents that can be sent by GCM
  •    com.google.android.c2dm.intent.RECEIVE
  •   com.google.android.c2dm.intent.REGISTRATION
  •  By setting the com.google.android.c2dm.permission.SEND permission, only intents sent by the GCM system framework are sent to the receiver
  •   Notice that android:name in the category tag must be replaced by your application's package name

                  5. Add the following intent service:


<service android:name=".GCMIntentService" />

    This intent service will be called by the GCMBroadcastReceiver, (which is is provided by GCM library)

Step 3: Write the my_app_package.GCMIntentService class


  • Next write the my_app_package.GCMIntentService class, overriding the following callback methods (which are called by GCMBroadcastReceiver)
  •   onRegistered(Context context, String regId):
  •   onUnregistered(Context context, String regId):
  •   onMessage(Context context, Intent intent)
  •   nRecoverableError(Context context, String errorId)

Step 4: Write your application's main activity

Add the following import statement in your application's main activity
import com.google.android.gcm.GCMRegistrar;
In the onCreate() method, add the following code:
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
  GCMRegistrar.register(this, SENDER_ID);
} else {
  Log.v(TAG, "Already registered");
}


  •  The checkDevice() method verifies that the device supports GCM or not
  •    Similarly, the checkManifest() method verifies that the application manifest contains meets all the requirements or not
  •   the device calls GCMRegsistrar.register() to register the device
  •   GCMRegistrar is singleton keeps track of the registration ID upon the arrival of registration intents, you can call GCMRegistrar.getRegistrationId()

Note: It is possible that the device was successfully registered to GCM but failed to send the registration ID to your server, in which case you should retry. See Advanced Topics for more details on how to handle this scenario.

Writing the Server-side Application


  1. Copy the gcm-server.jar file from the SDK's gcm-server/dist directory to your server classpath.
  2. Create a servlet (or other server-side mechanism) that can be used by the Android application to send the registration ID received by GCM . The application might also need to send other information—such as the user's email address or username—so that the server can associate the registration ID with the user owning the device.
  3. Similarly, create a servlet used to unregister registration IDs.
  4. When the server needs to send a message to the registration ID, it can use thecom.google.android.gcm.server.Sender helper class from the GCM library. For example:


import com.google.android.gcm.server.*;

Sender sender = new Sender(myApiKey);
Message message = new Message.Builder().build();
MulticastResult result = sender.send(message, devices, 5);

The above code will do the following:
Ø  Creates a Sender object using your project's API key.
Ø  Creates a message using a given registration ID (the message builder also has methods to set all message parameters such as the collapse key and payload data).
Ø  Sends the message with a maximum of 5 retry attempts (in case the GCM servers are unavailable), and stores the response on result.

It's now necessary to parse the result and take the proper action in the following cases:
  • If the message was created but the result returned a canonical registration ID, it's necessary to replace the current registration ID with the canonical one.
  • If the returned error is NotRegistered, it's necessary to remove that registration ID, because the application was uninstalled from the device.

Here's a code snippet that handles these 2 conditions:
if (result.getMessageId() != null) {
 String canonicalRegId = result.getCanonicalRegistrationId();
 if (canonicalRegId != null) {
   // same device has more than on registration ID: update database
 }
} else {
 String error = result.getErrorCodeName();
 if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
   // application has been removed from device - unregister database
 }
}

Once the GCM setting up is completed.

Setting Up the Server


To set up the server using a standard, servlet-compliant web server

1.       From the SDK Manager, install Extras > Google Cloud Messaging for Android Library.
This creates a gcm directory under YOUR_SDK_ROOT/extras/google/ containing these subdirectories: gcm-client, gcm-server, samples/gcm-demo-client, samples/gcm-demo-server, and samples/gcm-demo-appengine.
2.       In a text editor, edit the samples/gcm-demo-server/WebContent/WEB-INF/classes/api.key and replace the existing text with the API key obtained above.
3.       In a shell window, go to the samples/gcm-demo-server directory.
4.       Generate the server's WAR file by running ant war:

$ ant war
Buildfile:build.xml
init:
   [mkdir] Created dir: build/classes
   [mkdir] Created dir: dist
compile:
   [javac] Compiling 6 source files to build/classes
war:
     [war] Building war: dist/gcm-demo.war
BUILD SUCCESSFUL
Total time: 0 seconds
5.       Deploy the dist/gcm-demo.war to your running server. For instance, if you're using Jetty, copy gcm-demo.war to the webapps directory of the Jetty installation.
6.       Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like http://local_IP_Address:8080/gcm-demo/home, where gcm-demo is the application context and /home is the path of the main servlet.


Fig Source – developer.android.com

You server is now ready.



Setting Up the Device


1.       From the SDK Manager, install Extras > Google Cloud Messaging for Android Library
This creates a gcm directory under YOUR_SDK_ROOT/extras/google containing these subdirectories: gcm-client, gcm-serversamples/gcm-demo-clientsamples/gcm-demo-server, and samples/gcm-demo-appengine.
2.       Using a text editor, open samples/gcm-demo-client/src/com/google/android/gcm/demo/app/CommonUtilities.java and set the proper values for the SENDER_ID and SERVER_URL constants. For example:

static final String SERVER_URL = "http://192.168.1.10:8080/gcm-demo";
static final String SENDER_ID = "4815162342";
3.       In a shell window, go to the gcm-demo-client directory.
4.       Use the SDK's android tool to generate the ant build files:

$ android update project --name GCMDemo -p . --target android-16
Updated project.properties
Updated local.properties
Updated file ./build.xml
Updated file ./proguard-project.txt
5.       Use ant to build the application's APK file:

$ ant clean debug
Buildfile: build.xml

...


-do-debug:
[zipalign] Running zip align on final apk...
    [echo] Debug Package: bin/GCMDemo-debug.apk
[propertyfile] Creating new property file: bin/build.prop
[propertyfile] Updating property file: bin/build.prop
[propertyfile] Updating property file: bin/build.prop
[propertyfile] Updating property file: bin/build.prop

-post-build:
debug:
BUILD SUCCESSFUL
Total time: 3 seconds

6.       Start the Android emulator
·         $emulator -avd my_avd

7.       Make sure there is a Google account added to the emulator. It doesn't have to be any account (like the senderId) in particular.
8.       Install the application in the emulator:

$ ant installd
Buildfile: gcm-demo-client/build.xml

-set-mode-check:

-set-debug-files:

install:
     [echo] Installing gcm-demo-client/bin/GCMDemo-debug.apk onto default emulator or device...
     [exec] 1719 KB/s (47158 bytes in 0.026s)
     [exec]   pkg: /data/local/tmp/GCMDemo-debug.apk
     [exec] Success

installd:

BUILD SUCCESSFUL
Total time: 3 seconds


9.       In the emulator, launch the GCM Demo app. The initial screen should look like this:



10.   Now go back to your browser and refresh the page. It will show that there is one device registered:



11.   Click on Send Message. The browser should show




And in emulator:-



 Source - developer.android.com