Power your mobile apps with android push notification (C2DM)

15 May 2011

Power your mobile apps with android push notification (C2DM)

Recently we were working on android application and we had requirements from our client to support push notification. We already had implemented Apple Push Notification Service for the iPhone application and thought there would be similar solution for android push too.  As android platform doesn’t have single vendor like Apple so we were wondering who would support it. There are many custom build solutions based on application polling or asynchronous connection to server but timing of these event was tricky part plug they is additional usage of network resource and battery.

Welcome to the world of  ‘Cloud to Device Messaging’ or C2DM supported by google services. This solution provides a  solution to send real time notification to the user on user’s handset. Since Google already uses its service for Calendar or gmail etc. on the android platform so there won’t be extra network usage or battery usage for c2dm.

There are plenty of excellent articles which explain working on C2DM push notification and provide sample code to Run. We feel some points were missing or not obvious in those articles specially when you are not aware of Push Notification concept. Also there is no default notification implementation on Android platform. So we decided to fill in the gap and allow developers to quickly run a sample android push application and recieve the push notification from third party server.

For this purpose, we created a sample application which registers the device to google service and send the registrationId to the our own third party server. The sample application displays the notification screen whenever a push notification is received by android application. You can find many server-side solutions for scripting language like php,shell script using curl etc. Since most of the enterprise applications run on J2EE platform so we decided to have a J2EE server-side solution. In our server-side implementation, you can regsiter device with registerId, view list of registerId and can send sample push to the client.

So the purpose of this article is to understand android push notification(c2dm) and start working on it quickly..Using this article developer can register the application from device and can send notification from web-interface. This way developer can also display push notification to clients or non-technical person.

There are three entity involved in android push notification:

  • Android application – registers the device with C2DM server and passes the registerId to third party server
  • Google’s C2DM servers – send messages to android device
  • Third Party Server – send messages to C2DM server

Sample Application for Android Push Notification (C2DM):

We have taken the source code from cw-advandroid and added few tweaks in the source code. The only thing you need to do is to download the code from below link and configure it in your favorite IDE (We would prefer to use eclipse though). You need to open strings.xml file inside res/values directory and change the server URL.

If you are deploying the server application (We shall discuss server-side in next section) on local machine then replace the ipaddress with your machine’s ipAddress. Now your application is ready to register your app with google and send the registrationId to your third party server.

Please notice few points before running the app on android:

  • You must have android sdk 2.2+ and google service must be running on your emulator (We would recommend to install google sdk 2.3.1)
  • You must register your Google account on your emulator. You can do it by going to Settings -> Accounts & Sync and add gmail account. You cannot receive push notification unless Google account is set.
  • You must register your developer’s email address for your application at google . Please note one thing that this account is developer’s account and might not be account which is configured in ‘Accounts & Sync’ settings.

Third party server to register device and send Android Push Notification (C2DM):

We have built server-side solution on J2EE platform and application can be deployed on tomcat server(It might deployed fine on other servers but hav’nt tested it). Before deploying to server, you need to set the authentication code for your developer account in the application so please set it in the AUTH_KEY variable in class com.myor.c2dm.utils.Constants.java

You can get authentication key using curl as mentioned this article or You can use the our utility com.myor.c2dm.utils.AuthenticationUtils

Please use maven to create war file and deploy it on your server web directory.

You can access the application at

Now we ready to register and receive the android push notification on sample application. Please launch the application on your emulator or device and screen would be displayed like this:

Sample application to register push notification

Sample notification application

Enter your developer email account and click on the ‘Register!’ button. This shall make a call to google service to register the device for application. In the callback method, we make call to our third party server to register the registrationId for the device. We can access the registerId at

List of devices registered on google service

List of devices registered on google service

Now we can send push notification to the android application by clicking the ‘Push’ link. The notification on the client–side look shall like this:

Android Push Notification Ticker text

Android Push Notification Ticker text

When you drag down the notification window then full notification shall be displayed like this:

Sample notification when a push notification is received by device

Push notification is received on device

We hope this article shall help you to power your application with Android push notification. Feel free to give us feedbacks or let us know if you have any queries.

References:

  • Ivan

    Hey this is some brilliant work you have for C2DM. the android client worked fine but im havin trouble to deploy the third party server on my eclipse with tomcat server. You mentioned that its a solution on J2EE platform but there are no .jar files in ur package. Nevertheless i created a new dynamic wed app and imported the zip files to its directory. When i load them on eclipse there seem to be a problem with the import org.slf4j. Im quite new to this so maybe im doing something wrong, please corrent me. Thanks

  • http://www.makeurownrules.com Kapil Jain

    Hey Ivan,

    Well Its Maven project and dynamically loads jar file from maven repository.Please check the pom.xml for dependencies. These are the dependencies for slf4j:

    slf4j-api 1.6.1
    slf4j-log4j12 1.6.1
    log4j-over-slf4j 1.6.1

    Hope this helps. Let me know if you have any issue.

    Cheers,
    Kapil

  • Andre Esteves

    We already got this working, but we are having a problem because we have two devices registered under the same email account and only one is shown at http://yourserver:port/c2dm/notify?act=1 .

    Is that correct or something is wrong?

    Thanks in advance,
    Esteves

  • http://www.makeurownrules.com Kapil Jain

    Hi Esteves,

    Ideally deviceToken should be unique for each device so I think something is wrong. Please check the logs on the client-side and check whether deviceToken is pushed to server.

    Let me know if there are any issues

    Cheers,
    Kapil

  • Andre Esteves

    We already have two devices registred under the same google account. Each device has a unique token. The problem is that the list of devices, only presents one device (the last one that we have registered).

    The list should present both devices instead of one, right?

    best regards,
    Esteves.

  • Prashant

    Hi I am a new developer on the android and also in deploying web services. I have a few basic questions and would really be thankful if they are answered

    1) I am workingon a Windows7 machine and I use Eclipse Helios. I have installed Tomcat 7.0 on my Windows 7 OS. Is this enough to deploy the server side code u have shared? or do I need a tomcat plugin in Eclipse

    2)AuthenticationUtils.getAuthCode(“”, “”)

    I am not very clear about how I should use the above to get the authentication key. Can someine please help?

    3) ALso is a maven add on into eclipse required to create a war deployable on Tomcat.

    Sorry for the basic nature of my questions. I have just about started to work on the above and need some direction.

    Thanks in advance

  • http://www.makeurownrules.com Kapil Jain

    1. You need to configure maven plugin for eclipse to generate war file
    2. Please add put your gmail username and password to get Auth Code
    3. You need to setup maven to generate war file

    I hope this would help you.Let me know if there are any issues.

  • Prashant

    Hi Kapil,

    Thankyou for your reply..

    1)I have installed the maven plugin for eclipse from the eclipse marketplace.

    2)Now I downloaded the Server version of the code and from eclipse created a dynamic web project setting the path as the locastion where I unzipped the rar file…Basically my path in the eclipse project now points to ..\…\c2dm.
    The target runtime that I use is Tomcat 7.0

    But when I try to do this I get the following error…
    ENTRY org.eclipse.wst.common.project.facet.core 4 0 2011-05-31 15:53:19.039
    !MESSAGE Failed while installing Dynamic Web Module 3.0.
    !STACK 0
    java.lang.NullPointerException
    at org.eclipse.jst.jee.model.internal.WebAnnotationReader.analyzeCompilationUnit(WebAnnotationReader.java:144)
    at org.eclipse.jst.jee.model.internal.WebAnnotationReader.loadModel(WebAnnotationReader.java:99)
    at org.eclipse.jst.jee.model.internal.common.AbstractAnnotationModelProvider.getConcreteModel(AbstractAnnotationModelProvider.java:106)
    at org.eclipse.jst.jee.model.internal.common.AbstractAnnotationModelProvider.getModelObject(AbstractAnnotationModelProvider.java:122)
    at org.eclipse.jst.jee.model.internal.common.AbstractMergedModelProvider.loadProviders(AbstractMergedModelProvider.java:265)
    at org.eclipse.jst.jee.model.internal.common.AbstractMergedModelProvider.access$2(AbstractMergedModelProvider.java:255)
    at org.eclipse.jst.jee.model.internal.common.AbstractMergedModelProvider$LoadModelsWorkspaceRunnable.run(AbstractMergedModelProvider.java:278)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
    at org.eclipse.jst.jee.model.internal.common.AbstractMergedModelProvider.loadModel(AbstractMergedModelProvider.java:249)
    at org.eclipse.jst.jee.model.internal.common.AbstractMergedModelProvider.getMergedModel(AbstractMergedModelProvider.java:219)
    at org.eclipse.jst.jee.model.internal.Web25MergedModelProvider.modify(Web25MergedModelProvider.java:80)
    at org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDelegate.populateDefaultContent(WebFacetInstallDelegate.java:283)
    at org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDelegate.createWeb30DeploymentDescriptor(WebFacetInstallDelegate.java:229)
    at org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDelegate.execute(WebFacetInstallDelegate.java:111)
    at org.eclipse.wst.common.project.facet.core.internal.FacetedProject.callDelegate(FacetedProject.java:1478)
    at org.eclipse.wst.common.project.facet.core.internal.FacetedProject.modifyInternal(FacetedProject.java:442)
    at org.eclipse.wst.common.project.facet.core.internal.FacetedProject.mergeChangesInternal(FacetedProject.java:1182)
    at org.eclipse.wst.common.project.facet.core.internal.FacetedProject.access$2(FacetedProject.java:1118)
    at org.eclipse.wst.common.project.facet.core.internal.FacetedProject$5.run(FacetedProject.java:1100)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
    at org.eclipse.wst.common.project.facet.core.internal.FacetedProject.mergeChanges(FacetedProject.java:1110)
    at org.eclipse.wst.common.project.facet.core.internal.FacetedProjectWorkingCopy.commitChanges(FacetedProjectWorkingCopy.java:2020)
    at org.eclipse.wst.common.project.facet.ui.ModifyFacetedProjectWizard.performFinish(ModifyFacetedProjectWizard.java:400)
    at org.eclipse.wst.web.ui.internal.wizards.NewProjectDataModelFacetWizard.performFinish(NewProjectDataModelFacetWizard.java:282)
    at org.eclipse.wst.common.project.facet.ui.ModifyFacetedProjectWizard$3.run(ModifyFacetedProjectWizard.java:331)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
    at org.eclipse.wst.common.project.facet.ui.ModifyFacetedProjectWizard$4.run(ModifyFacetedProjectWizard.java:345)
    at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)

    Thanks

  • Prashant

    Hi

    Since I am attempting to deploy the server code on Eclipse Helios now, eclipse is going to use the jre and the internal compiler. Hence whenever I open eclipse I getthe following error:

    61/11 2:24:54 PM IST: Eclipse is running in a JRE, but a JDK is required
    Some Maven plugins may not work when importing projects or updating source folders….

    Can someone help please…

  • Tina

    I am getting
    Registration error SERVICE_NOT_AVAILABLE c2dm

    Can you suggest what could be the reason ?

  • http://www.makeurownrules.com Kapil Jain

    Please check you register email with google c2dm. If you still not got the confirmation mail for your email then signup again to get rid of error SERVICE_NOT_AVAILABLE c2dm

  • http://www.makeurownrules.com Kapil Jain

    Hi Prashank,

    Is your problem resolved now ?

    Cheers,
    Kapil

  • Joao

    Hi,

    I can’t get the registrationId for device on my third party server. After “register” on Android app, the http://myserver:port/c2dm/notify?act=1 is empty. On log of my device I can see that he gets the registerID.
    I’ve done the 3 points you refer to do before running the app on android.
    I’me running the android app on sdk2.2 and using glassfish3.

    Do you have any advice to give me?

    Thks,
    João

  • http://www.makeurownrules.com Kapil Jain

    Hi Joao,

    If you are able to view the registrationId then it seems the request is not sent to the server. can you make sure that you have configured server url properly ?

    Cheers,
    Kapil

  • Joao

    Hi Kapil,

    Thanks for your feedback.
    I’ve configured the server url properly.
    Is there any way to check if request is sent to the server?

    Thks,
    Joao

  • michael

    Hi,
    after the sending msg to the client nothing happens…

    Response from post call is HTTP/1.1 200 OK
    id=0:1311659103747994%9a6f55cd00000030

  • michael

    ddms.bat shows
    WARN/C2DMReceiver(583): alert text after a while, great! but client `ve not changed looks

  • michael

    looks great! works fine! thanks

  • vamsi prakash

    hi kapil ,

    i am able to see my device registered on server at link http://yourserver:port/c2dm/notify?act=1 but, while clicking on push , i am not getting any notification in my app, what might be the problem ?

  • anil

    hi,
    thanks for nice stuff.

    in references
    Demo to send notification.

    what all the information i need to enter.


    Anil

  • Rakesh

    i am able to see my device registered on server at link http://yourserver:port/c2dm/notify?act=1 but, while clicking on push , i am not getting any notification in my app, what might be the problem ?

  • http://www.makeurownrules.com Kapil Jain

    well check the role account on ur device/simulator ?

  • anil

    hi Kapil Jain

    i am new to install server and deploying project
    i have gone through all previous posts.
    still i am not getting how to load into server
    please give me the requirement to load server side program into tomcat server

    and how to register android developer

    thanks in advance

    -Anil

  • Rakesh

    We already have two devices registred under the same google account. Each device has a unique token. The problem is that the list of devices, only presents one device (the last one that we have registered).

    The list should present both devices instead of one, right?

  • http://www.kammerath.net/ Jan

    I compared the different types of push notifications:
    http://www.kammerath.net/push-notification.html

    Greetings,

    Jan