SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

Embed Size (px)

Citation preview

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    1/38

    Software Engineering

    Competence Center

    TUTORIAL

    How To Develop Smart Android Notificationsusing Google Cloud Messaging Service

    Ahmed Mohamed GamaleldinSenior R&D Engineer-SECC

    [email protected]

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    2/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 2

    Abstract

    Google Cloud Messaging for Android (GCM) is a service that helps developers to

    send data from servers to their Android applications on Android devices. The

    service was unveiled on June 27, 2012, at Google I/O 2012 held at the Moscone

    Center in San Francisco [1]. The GCM service handles all aspects of queuing of

    messages and delivery to the target Android application running on the target

    device. It is completely free whatever your messaging needs are and it can be

    used in some applications like smart notification systems.

    This tutorial gives an overview about the Google GCM service and provides

    hands-on experience on using this technology in a case study for energy-aware

    smart home application developed at Software Engineering Competence Center

    (SECC).

    Keywords:Google Cloud Messaging (GCM), Cloud to Device Messaging (C2DM),

    Android smart notifications.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    3/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 3

    Table of Contents

    1. Introduction 42. Getting started with the GCM service 43. How the GCM works? 103.1. GCM Lifecycle 124. Example of Android Application that Uses the GCM 125. Architecture of Android Application that uses GCM 145.1. GCM process flow 145.1.1. Enabling GCM 155.1.2. Sending a message 155.1.3. Receiving a message 165.2. Application server App 165.3 Android App 185.3.1 Creating the Manifest file 195.3.2 Android app structure 226. Invoker Application 346.1. Invoker example architecture 357. Summary 378. References 389. Abbreviations 38

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    4/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 4

    1.IntroductionGoogle Cloud Messaging for Android (GCM) is a service that allows you to send

    data from your server to the users' Android-powered device. This could be a

    lightweight message telling your app there is new data to be fetched from the

    server like new version of apps or something like that [1].

    The GCM service handles all aspects of storing, queuing and delivery of messages

    to the target Android application running on the target device. It is a completely

    free service whatever your messaging needs are.

    Google Cloud Messaging technology is the new version of the C2DM (cloud to

    device messaging) technology as the C2DM service has been officially deprecated

    as of June 26, 2012 which means that C2DM has stopped accepting new users

    and quota requests. The GCM could be considered as a more efficient

    implementation of the C2DM technology.

    The GCM service has many characteristics as described in [2]:

    1. It allows 3rd-party application servers to send messages to their Androidapplications. This is a key feature as you always need your server

    application to be in direct contact with the mobile application such that

    you can send messages to the mobile application about new versions for

    instance.

    2. An Android application on an Android device doesn't need to be runningto receive messages. The system will wake it up the Android application

    via Intent broadcast when the message arrives. This is achieved if the

    application is set up with the proper broadcast receiver and permissions

    in the AndroidManifest.xml file.

    3. The application has full control of how to handle the GCM messagespassed to it. For example, the application might post a notification when

    receiving these messages.

    4. It requires devices running Android 2.2 or higher that also have theGoogle Play Store application installed.

    2.Getting started with the GCM serviceTo start writing an Android application and the server-side application using the

    client and server helper libraries provided by GCM, you must begin with the first

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    5/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 5

    step which is creating a Google API project. The following steps explain how the

    Google API project is created [1]:

    1. Open the Google API console pagehttps://code.google.com/apis/console/

    2. If you haven't created an API project yet, this page will ask you to do so:

    3. If you already have existing projects, the first page you see will be theDashboardpage. From there you can create a new project by opening the

    project drop-down menu (upper left corner) and choosing Other

    projects > Create.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    6/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 6

    4. After creating the project. Your browser URL will change to somethinglike: https://code.google.com/apis/console/#project:514132917049Youll need to keep the value after #project: (514132917049 in this

    example). This is your project number, and it will be used later on as the

    GCM sender ID.

    5. It is required now to enable the GCM service through the following steps:a. In the main Google APIs Console page, select Services.

    b. Turn the Google Cloud Messagingtoggle to ON.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    7/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 7

    c. In the Terms of Service page, accept the terms.

    6. After enabling the service, the API key is required. To obtain it:In the main Google APIs Console page, select API Access. You will see a

    screen as like:

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    8/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 8

    7. Click Create new Server key. Note that either a server key or a browserkey should work. The advantage of using a server key is that it gives youmore control on the IP addresses that can access your app (this feature isnot used in our application below). The following screen appears, just

    click the Create button:

    8. Take note with the API key that is shown after that:

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    9/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 9

    9. Up to this step, you have finished creation of the Google API proejct andtoke a note with the project number and the API key. For development,youll need to install the helper libraries from the SDK manager as follow:

    From the SDK Manager, install Extras > Google Cloud Messaging forAndroid Library. This creates a gcmdirectory underYOUR_SDK_ROOT/extras/google/containing these subdirectories: gcm-

    client, gcm-server, samples/gcm-demo-client, samples/gcm-demo-server, andsamples/gcm-demo-appengine

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    10/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 10

    3.How the GCM works?There are some key terms and concepts involved in the GCM service and it is

    very important to have a good knowledge about them. The key terms and

    concepts of the GCM are divided into two categories [2]:

    Components The physical items involved in GCM steps. Credentials The IDs that are used in different stages of GCM to achieve

    the authentication, and to be sure that the message is going to the correct

    application and the correct Android device.

    Table 1 below explains the previous GCM concepts with clear examples

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    11/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 11

    Table 1 GCM concepts

    Components

    Mobile Devices The device that is running an Android application that uses

    GCM

    3rd-party Application Server The 3rd-party application server sends data to an Android

    application on the device via the GCM server.

    GCM Servers The Google servers used in taking messages from the 3rd-party application server and sending them to the device.

    Credentials

    Sender ID A project number you acquire from the API console. The sender ID is

    used in the registration process to identify an Android application thatis permitted to send messages to the device

    Application ID The Android application that is registering to receive messages. The

    Android application is identified by the package name from the

    manifest.xml file. This ensures that the messages are targeted to the

    correct Android application

    Registration ID An ID issued by the GCM servers to the Android application that allowsit to receive messages. Once the Android application has the

    registration ID, it sends it to the 3rd-party application server, which

    uses it to identify each device that has registered to receive messages

    for a given Android application. In other words, a registration ID is tied

    to a particular Android application running on a particular device.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    12/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 12

    Google User Account For GCM to work, the mobile device must include at least one Google

    account if the device is running a version lower than Android 4.0.4.

    Sender Auth Token An API key that is saved on the 3rd-party application server that givesthe application server authorized access to Google services. The API

    key is included in the header of POST requests that send messages.

    3.1. GCM LifecycleThe usage of the GCM process requires the following phases:

    1. Enabling GCM - An Android application running on a mobile deviceregisters itself to be able to receive messages.

    2. Sendin g a message - A 3rd-party application server sends messages tothe device.

    3. Receiv in g a message -An Android application receives a message from aGCM server.

    4.Example of Android Application that Uses the GCMThis section will explain an Android application used in the energy-aware smarthome project developed by SECC. This app was based on the GCM demo

    application provided by Google [3]. Well cover the details of that application

    with all of the code snapshots in the next section

    The android application architecture is described in Error! Reference source not

    found.. It consists of three parts:

    1. Application server App (Here called GCM server)2. GCM client App (the Android App)3.

    GCM cloud service

    The following is an explanation for the scenario shown in Error! Reference

    source not found.

    1. At the device start up, the installed Android app (GCM client) sends aregistration request to the GCM server asking for a registration id. This

    registration request uses the Google API project ID to identify the

    Android device that asks for the registration id.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    13/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 13

    2. The GCM server responds to the previous request and sends theregistration id to the Android device. The Android app sends this

    registration id to server application which stores it in its internal storage.

    Figure 1 GCM application example in smart home building application

    3. The fault detector KP is subscribed for smart home devices faults. When itdetects any fault, it invokes the server application

    4. The server application sends a message to the Android device, where itsends a request to the GCM server via its helper classes APIs including theGoogle API project ID and the server API key.

    5. When the GCM server finds the Android device online, itll pass themessage to it through a broadcast intent. The broadcast receiverGCMIntentService intent in the Android device is responsible forreceiving this broadcast message and invoking the notification manager

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    14/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 14

    to create a new notification.

    First, we need to state the list of tools required to develop this App. Table 1

    shows these tools

    Tool

    Eclipse Indigo or Eclipse Juno

    Android ADT plugin

    Apache Tomcat Application server v7.1or later

    Apache Ant 1.8 or later

    For the web server: Ant 1.8, it is a project building tool and it is used for building the server-

    side application as a .war file

    A running web server compatible with Servlets API version 2.5, such asTomcat 7

    Google account registered to use GCM. The API key for that account.

    For the Android application:

    Eclipse with the ADT plugin Emulator (or device) running Android 2.3 (Ginger-bread) or higher with

    Google APIs.

    The Google API project number of the account registered to use GCM.5.Architecture of Android Application that uses GCM

    In this section, well cover in details the architecture of the Android app

    that uses the GCM service and also well cover the 3d party application

    server app.

    5.1.GCM process flowAs mentioned above the GCM service has three main steps:

    Enabl ing GCM Sendin g a message Receiv in g a message

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    15/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 15

    5.1.1. Enabling GCMThis is the sequence of events that occurs when an Android application

    running on a mobile device registers itself into the GCM server to receive

    messages:

    1. The first time the Android application needs to use the messagingservice, it sends registration intent to a GCM server.

    This registration Intent (com.google.android.c2dm.intent.REGISTER)

    includes the sender ID, and the Android application ID.

    2. If the registration is successful, the GCM server broadcasts acom.google.android.c2dm.intent.REGISTRATIONintent which gives the

    Android application a registration ID.

    The Android application should store this ID for later use (for

    instance, to check on onCreate()if it is already registered).

    3. To complete the registration, the Android application sends theregistration ID to the application server. The application server stores

    the registration ID in a database.

    5.1.2. Sending a messageFor an application server to send a message to an Android application,

    the following things must be in place:

    The Android application has a registration ID that allows it toreceive messages for a particular device.

    The 3rd-party application server has stored the registration ID. An API key. It is a key for the application on the application server

    and it is previously set up in the api.key file that exists in the

    application server app that will be explained later.

    Here is the sequence of events that occurs when the application server

    sends a message:

    1. The application server sends a message to GCM servers.2. GCM servers store the message in case the device is offline.3. When the device is online, Google sends the message to the device.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    16/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 16

    5.1.3. Receiving a messageThis is the sequence of events that occurs when an Android

    application installed on a mobile device receives a message:

    1. The system receives the incoming message and extracts any data fromit, if any.

    2. The system passes the key/value pairs to the targeted Androidapplication in a com.google.android.c2dm.intent.RECEIVEIntent as a

    set of extras.

    3. The Android application processes the message5.2.Application server App

    The application server used here is the Apache Tomcat v7.0 which is a servlet

    container that can accept HTTP requests and send HTTP commands to the

    GCM server. We dont need to develop a new application server where the

    GCM Demo server application provided by Google can be used directly. The

    following steps explain how to use it:

    1. From the SDK Manager, install Extras > Google Cloud Messaging forAndroid Library.

    2. 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.3. You can create a web application from Eclipse and copy the gcm-demo-

    server app into it as shown below4. In a text editor or from inside Eclipse, edit the samples/gcm-demo-

    server/WebContent/WEB-INF/classes/api.key and replace the existingtext (if any) with the API key obtained above.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    17/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 17

    $ ant war

    Bui l df i l e: bui l d. xml

    i ni t :[ mkdi r ] Cr eat ed di r : bui l d/ cl asses[ mkdi r ] Cr eat ed di r : di st

    compi l e:[ j avac] Compi l i ng 6 sour ce f i l es t o bui l d/ cl asses

    war:[ war ] Bui l di ng war: dist/gcm-demo.war

    BUI LD SUCCESSFULTota t i me: 0 secon s

    5. In a shell window, go to the samples/gcm-demo-server directory.6. Generate the server's WAR file by running ant war:

    Now the .war file is ready to be deployed into your application server, For

    instance, if you're using Tomcat as in our case, copy gcm-demo.war to the

    ${CATALINA_HOME}/webapps directory of the Tomcat installation. Starting

    the Tomcat will make this application running waiting for inquires that will

    be sent to it from the invoker app that will be explained later.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    18/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 18

    For more information about how the 3rdparty application server works, and

    how it sends messages either in text or JSON format, you can refer to [2]

    5.3 Android AppTo write Android applications that use GCM, you must have an application

    server described above. This section describes the steps you take to create a

    client application that uses GCM.

    Our client app is based on the gcm-demo-client app that exists in

    YOUR_SDK_ROOT/extras/google/samples

    You can follow these steps to use the gcm-demo-client app:

    1- Create new Android project in Eclipse with the name gcm-demo-client2- Copy the package com.google.android.gcm.demo.app from

    YOUR_SDK_ROOT/extras/google/samples/gcm-demo-client and paste it

    in the eclipse project

    3- Add the gcm.jar file into your projects libs1directory (this is done by justcopying it into libs folder)

    4- Open the AndroidManifest.xml fromYOUR_SDK_ROOT/extras/google/samples/gcm-demo-client and copy its

    contents in the AndroidManifest.xml file in your local eclipse project

    You must see now the following project structure:

    1The libs directory is by default existing in the project class path so if you dont want to add gcm.jar inthis directory, youll just need to add the path of it into your class path

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    19/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 19

    There are two primary steps involved in writing a client Android application:

    Creating a manifest that contains the permissions the Androidapplication needs to use GCM.

    Implementing your code. To use GCM, this implementation mustinclude:

    o Code to start and stop the registration service.o Receivers for the com.google.android.c2dm.intent.RECEIVE and

    com.google.android.c2dm.intent.REGISTRATIONintents.

    5.3.1 Creating the Manifest fileEvery Android application must have an AndroidManifest.xml file in its root

    directory. The manifest presents essential information about the Android

    application to the Android system. To use the GCM feature, the manifest mustinclude the following:

    The com.google.android.c2dm.permission.RECEIVE permission so theAndroid application can register itself and receive messages.

    The android.permission.INTERNET permission so the Androidapplication can send the registration ID to the 3rd party server.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    20/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 20

    The android.permission.GET_ACCOUNTSpermission as GCM requires aGoogle account (necessary only if the device is running a version

    lower than Android ICS 4.0.4)

    The android.permission.WAKE_LOCK permission so the applicationcan keep the processor from sleeping when a message is received.

    An application package + ".permission.C2D_MESSAGE permission toprevent other Android applications from registering and receiving the

    Android application's messages. The permission name must exactly

    match this patternotherwise the Android application will not

    receive the messages.

    A receiver for com.google.android.c2dm.intent.RECEIVEand

    com.google.android.c2dm.intent.REGISTRATION, with the category set

    as application package. The receiver should require thecom.google.android.c2dm.SENDpermission, to ensure that only intents

    sent by the GCM system framework are sent to the receiver (a regular

    application cannot issue intents with that permission).

    This broadcast receiver is responsible for handling the above 2 intents

    that can be sent by GCM (com.google.android.c2dm.intent.RECEIVEand

    com.google.android.c2dm.intent.REGISTRATION) and it is defined here

    in the manifest file so that these intents can be received even if the

    application is not running.

    An intent service to handle the intents received by the broadcastreceiver. This intent service will be called by the

    GCMBroadcastReceiver (which is provided by the GCM library). It

    could be a subclass of com.google.android.gcm.GCMBaseIntentService,

    and it must contain a public constructor, and should be named

    my_app_package.GCMIntentService

    Set android:minSdkVersion="8" in the manifest. This ensures that theAndroid application cannot be installed in an environment in which it

    could not run properly.

    Heres the AndroidManifest.xml file of the gcm-demo-client project

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    21/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 21

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    22/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 22

    5.3.2 Android app structureThe client application is consisting of 4 files:

    1. CommonUtilities.javaThis file includes the definitions of two main variables

    SERVER_URL, the server app url for e.g.,http://10.130.201.80:8080/gcm-demo

    SENDER_ID , Google API project IDThis file will look like this:

    packagecom.google.android.gcm.demo.app;

    importandroid.content.Context;importandroid.content.Intent;

    /*** Helper class providing methods and constants common to other classes in the* app.*/

    publicfinalclassCommonUtilities {

    /**

    * Base URL of the Demo Server (such as http://my_host:8080/gcm-demo)*/staticfinalString SERVER_URL= "http://10.130.201.80:8080/gcm-demo";

    /*** Google API project id registered to use GCM.*/

    staticfinalString SENDER_ID= "514132917049";

    /*** Tag used on log messages.*/

    staticfinalString TAG= "GCMDemo";

    /*** Intent used to display a message in the screen.*/

    staticfinalString DISPLAY_MESSAGE_ACTION="com.google.android.gcm.demo.app.DISPLAY_MESSAGE";

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    23/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 23

    2. GCMIntentService.javaThis class extends GCMBaseIntentService and it represents theintent service responsible for handling GCM messages. In this classwe are overriding the following callback methods (which are calledby GCMBroadcastReceiver):

    onRegistered(Context context, String regId): Called after aregistration intent is received, passes the registration ID

    assigned by GCM to that device/application pair as parameter.Typically, you should send the regid to your server so it can use

    it to send messages to this device.

    onUnregistered(Context context, String regId): Called after thedevice has been unregistered from GCM. Typically, you should

    send the regid to the server so it unregisters the device.

    onMessage(Context context, Intent intent): Called when yourserver sends a message to GCM, and GCM delivers it to the

    device. If the message has a payload, its contents are available

    as extras in the intent.

    onError(Context context, String errorId): Called when thedevice tries to register or unregister, but GCM returned an

    error. Typically, there is nothing to be done other than

    evaluating the error (returned by errorId) and trying to fix the

    problem.

    onRecoverableError(Context context, String errorId): Calledwhen the device tries to register or unregister, but the GCM

    /*** Intent's extra that contains the message to be displayed.*/

    staticfinalString EXTRA_MESSAGE= "message";

    /*** Notifies UI to display a message.*

    * This method is defined in the common helper because it's used both by* the UI and the background service.** @paramcontext application's context.* @parammessage message to be displayed.*/

    staticvoiddisplayMessage(Context context, String message) {Intent intent = newIntent(DISPLAY_MESSAGE_ACTION);intent.putExtra(EXTRA_MESSAGE, message);context.sendBroadcast(intent);

    }}

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    24/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 24

    Log.i(TAG, "Ignoring unregister callback");}

    }@OverrideprotectedvoidonMessage(Context context, Intent intent) {

    Log.i(TAG, "Received message");String message = getString(R.string.gcm_message);displayMessage(context, message);

    // notifies user with the new messagesgenerateNotification(context, message);}

    @OverrideprotectedvoidonDeletedMessages(Context context, inttotal) {

    Log.i(TAG, "Received deleted messages notification");String message = getString(R.string.gcm_deleted, total);displayMessage(context, message);// notifies usergenerateNotification(context, message);

    }

    @Override

    publicvoidonError(Context context, String errorId) {Log.i(TAG, "Received error: "+ errorId);displayMessage(context, getString(R.string.gcm_error, errorId));

    }

    @OverrideprotectedbooleanonRecoverableError(Context context, String errorId) {

    // log messageLog.i(TAG, "Received recoverable error: "+ errorId);displayMessage(context, getString(R.string.gcm_recoverable_error,

    errorId));returnsuper.onRecoverableError(context, errorId);

    }/**

    * Issues a notification to inform the user that server has sent a message.*/privatestaticvoidgenerateNotification(Context context, String message) {

    inticon = R.drawable.ic_stat_gcm;longwhen = System.currentTimeMillis();NotificationManager notificationManager = (NotificationManager)

    context.getSystemService(Context.NOTIFICATION_SERVICE);Notification notification = newNotification(icon, message, when);String title = context.getString(R.string.app_name);Intent notificationIntent = newIntent("android.intent.action.VIEW",

    Uri.parse("http://10.130.201.80:8080/ECWebSec/"));// set intent so it does not start a new activitynotificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|

    Intent.FLAG_ACTIVITY_SINGLE_TOP);

    PendingIntent intent =PendingIntent.getActivity(context, 0, notificationIntent, 0);

    notification.setLatestEventInfo(context, title, message, intent);notification.flags|= Notification.FLAG_AUTO_CANCEL;notificationManager.notify(0, notification);

    }}

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    25/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 25

    servers are unavailable. The GCM library will retry the

    operation using exponential backup, unless this method is

    overridden and returns false. This method is optional and

    should be overridden only if you want to display the message to

    the user or cancel the retry attempts.

    This file will look like this:

    packagecom.google.android.gcm.demo.app;importstaticcom.google.android.gcm.demo.app.CommonUtilities.SENDER_ID;importstaticcom.google.android.gcm.demo.app.CommonUtilities.displayMessage;importandroid.app.Notification;importandroid.app.NotificationManager;importandroid.app.PendingIntent;importandroid.content.Context;importandroid.content.Intent;importandroid.net.Uri;importandroid.util.Log;importcom.google.android.gcm.GCMBaseIntentService;importcom.google.android.gcm.GCMRegistrar;

    /*** IntentService responsible for handling GCM messages.*/

    publicclassGCMIntentService extendsGCMBaseIntentService {

    @SuppressWarnings("hiding")privatestaticfinalString TAG= "GCMIntentService";

    publicGCMIntentService() {super(SENDER_ID);

    }

    @OverrideprotectedvoidonRegistered(Context context, String registrationId) {

    Log.i(TAG, "Device registered: regId = "+ registrationId);displayMessage(context, getString(R.string.gcm_registered));ServerUtilities.register(context, registrationId);

    }@Override

    protectedvoidonUnregistered(Context context, String registrationId) {Log.i(TAG, "Device unregistered");displayMessage(context, getString(R.string.gcm_unregistered));if(GCMRegistrar.isRegisteredOnServer(context)) {

    ServerUtilities.unregister(context, registrationId);} else{

    // This callback results from the call to unre ister made on

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    26/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 26

    3. ServerUtilities.javaThis is a helper class used to enable the Android app tocommunicate with the application server. It contains threemethods called:

    register()Posts the registration request to the register servlet

    deployed at the application server, this servlet accepts the

    request and stores the registration id in its database.

    unregister()Posts the unregister request to the unregister servlet

    deployed at the application server, this servlet accepts the

    request and removes the registration id from itsdatabase.

    Post()Posts the register or unregister request to the applicationserver

    This file will look like this:

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    27/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 27

    packagecom.google.android.gcm.demo.app;importstaticcom.google.android.gcm.demo.app.CommonUtilities.SERVER_URL;importstaticcom.google.android.gcm.demo.app.CommonUtilities.TAG;importstaticcom.google.android.gcm.demo.app.CommonUtilities.displayMessage;importcom.google.android.gcm.GCMRegistrar;importandroid.content.Context;importandroid.util.Log;importjava.io.IOException;importjava.io.OutputStream;importjava.net.HttpURLConnection;importjava.net.MalformedURLException;importjava.net.URL;importjava.util.HashMap;importjava.util.Iterator;importjava.util.Map;importjava.util.Map.Entry;importjava.util.Random;

    /*** Helper class used to communicate with the demo server.*/publicfinalclassServerUtilities {

    privatestaticfinalintMAX_ATTEMPTS= 5;privatestaticfinalintBACKOFF_MILLI_SECONDS= 2000;privatestaticfinalRandom random= newRandom();

    /*** Register this account/device pair within the server.** @returnwhether the registration succeeded or not.*/

    staticbooleanregister(finalContext context, finalString regId) {Log.i(TAG, "registering device (regId = "+ regId + ")");String serverUrl = SERVER_URL+ "/register";Map params = newHashMap();params.put("regId", regId);longbackoff = BACKOFF_MILLI_SECONDS+ random.nextInt(1000);for(inti = 1; i

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    28/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 28

    Log.d(TAG, "Thread interrupted: abort remainingretries!");

    Thread.currentThread().interrupt();returnfalse;

    }// increase backoff exponentiallybackoff *= 2;

    }}String message = context.getString(R.string.server_register_error,

    MAX_ATTEMPTS);CommonUtilities.displayMessage(context, message);returnfalse;

    }

    /*** Unregister this account/device pair within the server.*/

    staticvoidunregister(finalContext context, finalString regId) {Log.i(TAG, "unregistering device (regId = "+ regId + ")");String serverUrl = SERVER_URL+ "/unregister";

    Map params = newHashMap();params.put("regId", regId);try{

    post(serverUrl, params);GCMRegistrar.setRegisteredOnServer(context, false);String message =

    context.getString(R.string.server_unregistered);CommonUtilities.displayMessage(context, message);

    } catch(IOException e) {// At this point the device is unregistered from GCM, but still// registered in the server.// We could try to unregister again, but it is not necessary:// if the server tries to send a message to the device, it will

    get

    // a "NotRegistered" error message and should unregister thedevice.

    String message =context.getString(R.string.server_unregister_error,

    e.getMessage());CommonUtilities.displayMessage(context, message);

    }}

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    29/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 29

    1. DemoActivity.javaThis class is the main UI of the application; it handles theregistration of the Android device when the activity starts

    /*** Issue a POST request to the server.** @paramendpoint POST address.* @paramparams request parameters.** @throwsIOException propagated from POST.*/

    privatestaticvoidpost(String endpoint, Map params)throwsIOException {

    URL url;try{

    url = newURL(endpoint);} catch(MalformedURLException e) {

    thrownewIllegalArgumentException("invalid url: "+ endpoint);}StringBuilder bodyBuilder = newStringBuilder();Iterator iterator = params.entrySet().iterator();// constructs the POST body using the parameterswhile(iterator.hasNext()) {

    Entry param = iterator.next();bodyBuilder.append(param.getKey()).append('=')

    .append(param.getValue());if(iterator.hasNext()) {

    bodyBuilder.append('&');}

    }String body = bodyBuilder.toString();Log.v(TAG, "Posting '"+ body + "' to "+ url);byte[] bytes = body.getBytes();HttpURLConnection conn = null;try{

    conn = (HttpURLConnection) url.openConnection();conn.setDoOutput(true);conn.setUseCaches(false);conn.setFixedLengthStreamingMode(bytes.length);

    conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type",

    "application/x-www-form-urlencoded;charset=UTF-8");// post the requestOutputStream out = conn.getOutputStream();out.write(bytes);out.close();// handle the responseintstatus = conn.getResponseCode();if(status != 200) {

    Log.d(TAG, "Post failed with error code");thrownewIOException("Post failed with error code "+ status);

    }} finally{

    if(conn != null) {conn.disconnect();

    }}

    }}

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    30/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 30

    4. DemoActivity.javaThis class is the main UI of the application; it handles theregistration of the Android device when the activity starts

    4.1Application registration:An Android application needs to register with GCM servers beforeit can receive messages. To register, the application sends Intent(com.google.android.c2dm.intent.REGISTER), with 2 extraparameters:

    o Sender is the project number of the accountauthorized to send messages to the Android

    application.

    o App is the Android application's ID, set with aPendingIntent to allow the registration service to

    extract Android application information.

    This registration can be done easily using the GCMRegstrar object

    GCMRegistrar.register(this, SENDER_ID);

    This intent will be asynchronously sent to the GCM server, and the

    response will be delivered to the application as a

    com.google.android.c2dm.intent.REGISTRATIONintent containing

    the registration ID assigned to the Android application running on

    that particular device.

    Registration is not complete until the Android application sends

    the registration ID to the 3rd-party application server, which in

    turn will use the registration ID to send messages to the

    application. This is done by calling

    ServerUtilities.register(context, regId);

    4.2Handling GCM intents:The manifest defines a broadcast receiver for the

    com.google.android.c2dm.intent.REGISTRATIONand

    com.google.android.c2dm.intent.RECEIVEintents. These intents are

    sent by GCM to indicate that a device was registered (or

    unregistered), or to deliver messages, respectively.

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    31/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 31

    Handling these intents might require I/O operations (such as

    network calls tothe 3rd party server), and such operations shouldnot be done in the receiver's onReceive() method. The

    recommended way to handle the intents is to delegate them to a

    service, such as a GCMIntentService explained above.

    This file will look like this:

    packagecom.google.android.gcm.demo.app;

    importstaticcom.google.android.gcm.demo.app.CommonUtilities.DISPLAY_MESSAGE_ACTION;importstaticcom.google.android.gcm.demo.app.CommonUtilities.EXTRA_MESSAGE;importstaticcom.google.android.gcm.demo.app.CommonUtilities.SENDER_ID;importstaticcom.google.android.gcm.demo.app.CommonUtilities.SERVER_URL;

    importcom.google.android.gcm.GCMRegistrar;

    importandroid.app.Activity;importandroid.content.BroadcastReceiver;importandroid.content.Context;importandroid.content.Intent;importandroid.content.IntentFilter;importandroid.graphics.Color;importandroid.net.Uri;importandroid.os.AsyncTask;importandroid.os.Bundle;importandroid.util.Log;importandroid.view.Menu;importandroid.view.MenuInflater;importandroid.view.MenuItem;importandroid.view.View;importandroid.widget.Button;importandroid.widget.TextView;

    /*** Main UI for the demo app.*/publicclassDemoActivity extendsActivity {

    TextView mDisplay;Button webSiteButton;AsyncTask mRegisterTask;privatestaticfinalString TAG= "Activity";

    @OverridepublicvoidonCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);checkNotNull(SERVER_URL, "SERVER_URL");checkNotNull(SENDER_ID, "SENDER_ID");

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    32/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 32

    // Make sure the device has the proper dependencies.GCMRegistrar.checkDevice(this);// Make sure the manifest was properly set - comment out this line

    GCMRegistrar.checkManifest(this);setContentView(R.layout.main);

    webSiteButton=(Button)findViewById(R.id.WebSiteButton);

    webSiteButton.setOnClickListener(newView.OnClickListener(){publicvoidonClick(View v){

    Intent intent = newIntent();intent.setAction(Intent.ACTION_VIEW);intent.addCategory(Intent.CATEGORY_BROWSABLE);intent.setData(Uri.parse("http://10.130.201.80:8080/ECWebSec/"));startActivity(intent);

    }});

    mDisplay= (TextView) findViewById(R.id.display);mDisplay.setText("\nSmart Home Notifier Application will send you a

    notifications in case of "+ "faults occured with your home devices."+"The application is based on Google Cloud Messaging Service (GCM).\n"+

    "The scenario is as follow:\n"+" 1- In case of fault occured, a faultdetector web service will be invoked. This web service sends the fault message tothe GCM server via a web application deployed in the application server\n"+

    " 2- The GCM server receives the message and routesit to the target Application which is running on your device.\n"+"**Developed by: SECC R&D Team. www.secc.org.eg\n\n\n");

    mDisplay.setTextColor(Color.WHITE);mDisplay.append("Log:");registerReceiver(mHandleMessageReceiver,

    newIntentFilter(DISPLAY_MESSAGE_ACTION));finalString regId = GCMRegistrar.getRegistrationId(this);if(regId.equals("")) {

    // Automatically registers application on startup.GCMRegistrar.register(this, SENDER_ID);Log.d(TAG, "Registered to GCM !!! ");

    } else{// Device is already registered on GCM, check server.if(GCMRegistrar.isRegisteredOnServer(this)) {

    // Skips registration.mDisplay.append(getString(R.string.already_registered) + "\n");

    } else{// Try to register again, but not in the UI thread.// It's also necessary to cancel the thread onDestroy(),// hence the use of AsyncTask instead of a raw thread.finalContext context = this;mRegisterTask= newAsyncTask() {

    @OverrideprotectedVoid doInBackground(Void... params) {

    booleanregistered =ServerUtilities.register(context, regId);

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    33/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 33

    if(!registered) {GCMRegistrar.unregister(context);

    }returnnull;

    }

    @OverrideprotectedvoidonPostExecute(Void result) {

    mRegisterTask= null;}

    };mRegisterTask.execute(null, null, null);

    }}

    }

    @OverridepublicbooleanonCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();inflater.inflate(R.menu.options_menu, menu);returntrue;

    }@OverridepublicbooleanonOptionsItemSelected(MenuItem item) {

    switch(item.getItemId()) {

    caseR.id.options_clear:mDisplay.setText(null);returntrue;

    caseR.id.options_exit:finish();returntrue;

    default:

    returnsuper.onOptionsItemSelected(item);}}

    @OverrideprotectedvoidonDestroy() {

    if(mRegisterTask!= null) {mRegisterTask.cancel(true);

    }unregisterReceiver(mHandleMessageReceiver);GCMRegistrar.onDestroy(this);super.onDestroy();

    }

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    34/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 34

    After developing the above application, you can now run the project to get the

    .apk file and install it in your Android-powered device. When running thisapplication you will see a screen like this:

    N.B: You must make sure that the application server app (gc-demo-server.war) isdeployed and running on tomcat

    6.Invoker ApplicationUp till now, you have both Android and the Application server apps running. In

    order to test the whole cycle youll need to develop an invoker application that

    privatevoidcheckNotNull(Object reference, String name) {if(reference == null) {

    thrownewNullPointerException(getString(R.string.error_config, name));

    }}

    privatefinalBroadcastReceiver mHandleMessageReceiver=

    newBroadcastReceiver() {@OverridepublicvoidonReceive(Context context, Intent intent) {

    String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);mDisplay.append(newMessage + "\n");

    }};

    }

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    35/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 35

    calls the application server app and asks it to send a message to the Android app.

    Once this message is received, the Android app will fire a notification for the

    user. In the practical cases, this invoker app is your end application that needs

    based on some logic to send notifications to the Android-powered device.

    6.1.Invoker example architectureThe invoker explained in this tutorial is composed of two files:

    1. Definitions.javaThis file is simply contains the project ID, it will look as follow:

    2. InvokeSendAllServlet.javaThis file is the core invoker which calls the sendAll servlet of the application

    server which is responsible for contacting the GCM server and asking it to send

    messages to the Android application. This file could be like this:

    packagecom.secc.SendNotificationViaGCMService;

    publicfinalclassDefinitions {

    staticfinalString SERVER_URL="http://10.130.201.80:8080/gcm-demo";

    /*** Google API project id registered to use GCM.*/

    staticfinalString SENDER_ID= "514132917049";}

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    36/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 36

    package com.secc.SendNotificationViaGCMService;import static com.secc.SendNotificationViaGCMService.Definitions.SERVER_URL;import java.io.IOException;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;

    import java.net.URL;

    public class InvokeSendAllServlet {

    public void invokeSendAllServlet() {String serverUrl = SERVER_URL + "/sendAll";

    try {post(serverUrl);

    } catch (IOException e) {}

    }private static void post(String endpoint)

    throws IOException {URL url;

    try {url = new URL(endpoint);

    } catch (MalformedURLException e) {throw new IllegalArgumentException("invalid url: " + endpoint);

    }HttpURLConnection conn = null;try {

    conn = (HttpURLConnection) url.openConnection();conn.setDoOutput(true);conn.setUseCaches(false);conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type",

    "application/x-www-form-urlencoded;charset=UTF-8");OutputStream out = conn.getOutputStream();

    out.close();int status = conn.getResponseCode();if (status != 200) {throw new IOException("Post failed with error code " + status);

    }} finally {

    if (conn != null) {conn.disconnect();

    }}

    }public static void main(String []args) {

    InvokeSendAllServlet invoke=new InvokeSendAllServlet();invoke.invokeSendAllServlet();

    }}

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    37/38

    How ToDevelop Smart Android Notifications using Google Cloud Messaging Service | Tutorial Page 37

    By running the above invoker app you should see a notification appeared.

    7.SummaryGoogle Cloud Messaging for Android (GCM) is a free and powerful service that

    helps developers to send data from servers to their Android applications

    running on Android-powered devices. This tutorial provides the basic concepts

    of this service with a detailed explanation of the GCM demo application provided

    by the Android SDK. The GCM service is very promising and it could be

  • 8/14/2019 SECC_Tutorials_How To Develop Smart Android Notifications using Google Cloud Messaging Service.pdf

    38/38

    considered the most optimized and powerful method for sending messages from

    servers to the Android devices without the need to have the Android application

    listens to the server in an endless loop.

    8.References[1]http://developer.android.com/google/gcm/gs.html[2]http://developer.android.com/google/gcm/gcm.html[3]http://developer.android.com/google/gcm/demo.html

    9.AbbreviationsGCM Google Cloud Messaging

    App Application

    HTTP Hypertext Transfer ProtocolAPI Application Programming Interface

    C2DM Cloud to Device Messaging

    KP Knowledge Processor