READ THIS FIRST
Update: 3-4-2016: If you're finding this blog and looking for information related to Azure Mobile Services, I'd strongly recommend checking out Azure Mobile Apps. Azure Mobile Apps is a new version (consider it a v2) of Azure's mobile backend support. All of the same features of Azure Mobile Services are there, with a lot of other very cool features to go along. You can read more about Azure Mobile Apps, and how to transition from Azure Mobile Services, here.With today’s release of the Android SDK for Windows Azure Mobile Services, I thought it would be a good idea to post a walkthrough of adding some features into the quick start application. The quick start, which you can download after spinning up a new Mobile Service, is a ToDo list. It’s a rather simple application which already makes use of the structured data storage capabilities of Mobile Services to save, update, and read todo items. In this post, we’ll look at how to push a notification out to each user whenever a todo item is added. On it’s own, this may not be very desirable behavior in an application (unless everyone else running it will do my todos for me), but you can combine the concepts from this post with others (like authentication) to push to a specific user if you want to. There are a number of steps we need to take once we have the todo list quick start application, but let’s start with that.
Update: Android SDK Version Support
Since a few people have asked or thought differently, I wanted to clear up what versions of Android are supported by the Mobile Services SDK. The short answer is 2.2 (or level 8) and up. The Mobile Services SDK will build and run with any device running 2.2 or greater. The reason why the quick start application requires 4.2 (level 17) is that it has it's targetSdkVersion in it's manifest file set to 4.2. That's all. The app will still run on 2.2, it's just set to build against 4.2.
Creating a Mobile Service and getting the quick start app
Since I’ve covered this aspect of getting started with Mobile Services on several occasions (and it’s very straight forward) I’m going to glaze over some of the details. If you don’t already have a Windows Azure account, you can sign up for one for free here. Once you’ve done that, you’ll have access to create 10 free Mobile Services. Next, you can watch this video to step through how to create your first Mobile Service and download the Android quick start application. If you don’t feel like watching the video, I’ll summarize the steps you need to take after logging into the portal.
Start by clicking the + NEW button in the bottom left. Select COMPUTE then MOBILE SERVICE and click CREATE. Enter a unique name for your Mobile Service (this is how your Mobile Service will be labeled in the portal and part of the URL that will point at your service), choose if you want to create a new or use an existing database (if you have any) and pick a REGION (data center) before proceeding. On the next screen, either choose to create a new server and enter admin credentials for it or pick an existing server / database and enter the creds for it. Click the check mark and your Mobile Service will start being created. After a little bit (it usually takes about twenty to thirty seconds) you can click on your Mobile Service and you’ll first be taken to the quick start page. Here, under CHOOSE PLATFORM select ANDROID and then follow the guide under Create a new Android app. Note that the first step isn’t necessary if you already have an IDE (we’ll assume Eclipse) with the Android SDK (at least 4.2) and ADT installed. Once you’ve created the TodoItem Table you can download your project. Next in Eclipse, go to Import under the File menu and choose Existing Projects into Workspace. Navigate to your project and select it and it should be imported into Eclipse and show up in the Package Explorer. If you want to, you can run the project now to see what the Todo list app looks like, but we’ll proceed on with adding authentication.
Getting set up in the Google API Console
The first step to getting ready to do push notifications requires us to go to the Google API Console. If you’ve never been to the API console before, you should be easily directed to create a new project. If not, open the drop down in the top left and go to Create under Other Projects (assuming you haven’t already created the project you want to use). Name your project whatever you want (the name will only be used to identify it in the API console). After creating or navigating to your project, the first screen you should see is the Services page. If not, click on the Services link in the top left of the console. You want to go down the list of services and find Google Cloud Messaging for Android and click the OFF toggle so it turns to ON:
Next, click the API Access link in the top left of the page. On the next page, you’ll see a Create new Server key… button, click that:
In the modal that appears, you could restrict IP addresses that would be allowed to make requests to GCM with this key, however, we’ll leave this blank since we don’t want to lock ourselves down. Click the Create button:
After that, you’ll have a new API key that will be valid for any IP:
Copy the API key value and return to the Windows Azure Portal. Once there, navigate to the PUSH tab for your Mobile Service. At the bottom of the PUSH page, you’ll be able to copy the API key in under google cloud messaging settings:
After that, go ahead and click the save button.
Installing the GCM Android Library
If you haven’t done so already, open up the Android SDK Manager. In Eclipse, you can do this by going to the Window menu and selecting Android SDK Manager or you can click the little Android button with the down arrow (it’s the one on the left in this image):
In the window that pops up, find the Extras folder and locate Google Cloud Messaging for Android Library. Check the box next to it (if it’s showing up with a Status of Not installed) and click the Install button in the bottom right:
Next, browse to the SDK path (in the image above it’s /Users/chrisner/code/android-sdk/macosx) and then go to the /extras/google/gcm/gcm-client/dist folder. Copy the gcm.jar from this folder into the libs folder of your project. This is the library that will enable you to hook into Google Cloud Messaging from your Android application.
Setting up your manifest
The next step is to return to Eclipse and open your AndroidManifest.xml file. Switch to xml view by clicking the AndroidManifest.xml tab at the bottom of the editor window. You should already see the android.permission.INTERNET, go ahead and paste this code beneath it:
One thing to point out is that here, I’ve put my own application’s package com.example.chrisandroid into the xml. Make sure you replace this with your own app package (which you can find at the top of the manifest xml). Next, find the </application> tag and paste this xml in above it:
Again, make sure you replace the com.example.chrisandroid with whatever your package is.
Adding a class to handle registration IDs
When our app registers with GCM, we’re going to get back a registration ID that identifies our device and app to the GCM servers. We’re going to save this data to a separate table in Mobile Services so we need to add a new data object to handle that. In Eclipse, right click on your project’s package and go to New and Class. We’ll name this class Registration. We’ll add the default id property to this object as well as a property to handle storing the Registration ID:
Now let’s work on getting the registration ID.
Registering with GCM
Open up your ToDoActivity.java class and add this import statement to the top of the file:
import com.google.android.gcm.GCMRegistrar;
Now that you’re importing GCMRegistrar, we can proceed by adding these two private variables to the class:
Make sure your SENDER_ID matches up with the ID of your project in the Google API Console. For example, if I return to where we left off in the console, my URL is showing up as https://code.google.com/apis/console/b/0/#project:794994939600:access. Now go ahead and add the following code after you instantiate your MobileServiceClient:
This code will essentially start the registration process if you haven’t already registered. Now we need to add a class to handle both getting the registration message back and receiving messages from the GCM server.
Inheriting GCMBaseIntentService
Right click on your package in Eclipse again and go to New and choose Class. Name your class GCMIntentService and set it’s superclass to com.google.android.gcm.GCMBaseIntentService. Start by dropping these import statements into the top of your file:
These libraries will be used to trigger a notification when a message is received. Now add the following constructor into your class:
This will handle calling the super constructor with the project ID you set in ToDoActivity.java. By default a number of methods were added to the class because of the base class you inherited from: onError, onMessage, onRegistered, and onUnregistered. We’re only going to implement two of these methods but we’ll talk about the other two later on. Let’s implement onMessage first:
Here we’re using NotificationCompat, which is part of the compatibility library, to build a notification. We then use NotificationManager to send the notification. This means it will show up in the notification drop down you see when you drag down from the top of the device. Next, we’ll implement the onRegistered method. I’m going to preface this by saying that this is NOT THE IDEAL WAY TO HANDLE THIS (I’ll explain more in a minute):
Here we’re creating a MobileServiceClient again. If I were building a real app, I would probably abstract my MobileServiceClient away so that I only create one instance of it and don’t have to repeat the URL or key (make sure you replace those with your own values before using this code by the way). However, since we’re trying to keep this brief, I’ve recreated it here. Next we get a MobileServiceTable for our Registration class and create a new instance of Registration and set it’s registration ID to the value returned from the GCM server. Last, we insert that into our table and log whether it was successful or not. We’re almost ready to run our app.
Handling things in the portal
Before we can run things, we need to go back to the portal. Go to the DATA tab and create a new table named Registration. You can leave the permissions as the default. Lastly, go to the TodoItem table and open it’s SCRIPT tab. Go to it’s Insert script and replace it with this:
This script handles inserting the todo item and then doing a push using GCM. It does this by reading the Registration table and sending a push through the push module’s gcm method to each Registration ID in the table. Now you can run your app.
Running the app
Go ahead and run your app (you need to make sure it’s either an emulator running on Google APIs (so it supports GCM) or a device that supports it (i.e. not one from Amazon)). After your app starts, you should be able to go to the portal and open the Registration table and see that a registration has been saved:
Go ahead and add a todo item. The first thing you should see after saving it is that an icon appears in the top left of your emulator or device:
This icon signifies that we’ve received a notification that is showing up in our Notification Manager. Now if you drag down from the top of the screen, you’ll see your notification:
Congratulations. With that you’ve received your first push notification from GCM using Mobile Services.
Conclusion
Today we walked through the steps necessary to add push notifications to your applications using Google Cloud Messaging and Windows Azure Mobile Services. There were a few methods we didn’t implement in the intent service including onError and onUnregistered. In a real application you would want to do something in these method so you would understand what was going on. For example, if you receive a message to onRegistered, you should let your server know to no longer send push notifications to that registration Id. Additionally, in ToDoActivity.java we were checking to see if GCMRegistrar.getRegistrationid(…) was set or not. If it is, you may want to check to see if you have already saved it to the server and if not, save it. Lastly, you’ll probably also want some way of making sure you don’t insert the same registration ID multiple times on the server (by deduping in the insert script for the Registration table). There are many improvements you could make over this sample but it should get you started with pushing information to your Android applications. You can access the completed source code for this application here. Remember that you’ll need to set your URL and app key in both the ToDoActivity and GCMIntentService classes in addition to getting things set up on the server (create the tables and set the insert script for TodoItem). Good luck with Mobile Services and let me know if you build anything with it.
11 Comments
Paul
Thanks Chris, if I want to work with mobile services in android I aways end up here. If a user uninstalls my app can I catch that an unregister?, or how would be best to handle this. Thanks for the great blog.
Chris
Hi Paul. Happy to hear this site is a good source of info. If the user uninstalls your app, you won't receive any notifications or have the chance to update your server to say they've unregistered. If you're dealing with push notifications though, you'll get a response back when you use push.gcm with a message about the registration ID being unregistered (take a look at #8 here: http://developer.android.co.... I would test this out so you can see the exact format of the message you will get back. ALso, take a look at this which talks more about how you can also get a mapping if you push to a registration ID and it's been updated on the GCM side: http://msdn.microsoft.com/e....
Thiago
Chris, I've downloaded your sample project and set my project url and key inside MobileServiceClient class and my SENDER_ID. I can create a todo item, it's appearing in my mobo app and in Azure Mobile Services data. But the push notification it's not working. Could you tell me your AVD settings, please?
Chris
Make sure your AVD is set to use Google APIs, it won't be able to register with GCM otherwise. Other debug steps are to check the Logging tab after attempting to deliver a push (Mobile Services should log if GCM returned any issues).
Joe
Hi Chris, I searched the web for a reliable push notifications provider and run into urban, parse, pushwoosh, appoxee but the costs are incredible... one of them asking for $500 per month. then I saw this http://www.pushapps.mobi that asking only $20 per month, but I don't know if fair price or not?
according to your professional opinion - How much do you think it is fair to pay for that service? what are the steps I should do before choosing the right push notifications service?
Have you tried one of them that you recommend?
KN
Hi Chris,
I followed your tutorial step by step. It registers and insert into mobile service well. But I can't receive any notifications. I tried a lot but onMessage never called. Is there any reasons?
PS: I downloaded your complete code but it didn't work too.
Chris
Did you set everything up in the Google Code Console and the Mobile Services portal and put all of the correct keys into your app? Are you getting a registration ID from GCM?
Trường Kỷ Nguyễn
Yes, sure about that. I have some devices, some receive notifications, some don't.
Chris
I would send an email to [email protected] or file a bug here so the team can look into your specific Mobile Service: https://social.msdn.microso...
Hemanshu
Hi Chris, i followed the article step by step but never got any Push message, device and everything is getting registered but in logs i get an error "[Error: 400 - The supplied notification payload is invalid. "
Chris
With the change from using a custom push system behind the scenes to using Azure Notification Hubs, there are a few modifications you may need to make. I'd recommend walking through this tutorial: http://azure.microsoft.com/...