Tutorial on how to add AirBop and Google Cloud Messaging to an Android app.
This article is a general overview of integrating Google Cloud Messaging into your Android app, registering your app with the AirBop servers, and responding to AirBop push notifications.
While there are some details specific to AirBop, the developer documentation for Google Cloud Messaging still applies. For an in-depth reference, visit Google's developer documentation for Google Cloud Messaging for Android.
The following items are required to work with AirBop's servers and discussed in this article:
Note: If you haven't already, you'll first want to read the article Getting Started with AirBop which describes the steps needed to start using AirBop. To see how all of these bits and pieces fit together, refer to the AirBop-Client sample on GitHub.
The gcm.jar file is a component of the Google Cloud Messaging for Android Library, and is the easiest way to add GCM support to your app.
Using the Android SDK Manager, install Extras > Google Cloud Messaging for Android Library. This will create a series of gcm subdirectories in the SDK_ROOT/extras/google/ folder. The 'gcm.jar' file is located in the gcm-client/dist subdirectory.
Note: The Google Cloud Messaging for Android Library is only available in version 20 or higher of the SDK Manager.
Copy the gcm.jar file from the SDK's gcm-client/dist directory to your application's libs directory.
Here are the changes you need to make to your application manifest for Google Cloud Messaging and AirBop integration.
GCM requires Android 2.2 or later, which translates to Android SDK version 8. This means that you will need to set minSdkVersion to 8 or higher in your application manifest. In other words, you will need at least the following declaration (where xx denotes the target version for your application):
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="xx"/>
Add a custom permission to your manifest so that your application will receive the appropriate GCM messages, replacing "my_app_package" with your package name:
<permission android:name="my_app_package.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="my_app_package.permission.C2D_MESSAGE" />
Note: The above permission is not required if you are targeting Android version 4.1 or above (minSdkVersion 16).
Add the following GCM related 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" />
You need to declare a broadcast receiver to handle the 'RECEIVE' and 'REGISTRATION' intents sent by GCM. You can use the GCMBroadcastReceiver provided in the GCM library by adding this declaration to your manifest:
<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>
The 'SEND' permission ensures that only intents sent by the GCM system framework are sent to the receiver.
Note: remember to replace my_app_package with your app's package name.
The GCM library assumes that you have a class named GCMIntentService with overridden methods to handle various GCM events.
The overridden methods will be called by the standard GCMBroadcastReceiver provided in the GCM library. Unless you're using a custom BroadcastReceiver, you need to declare this intent service in your application manifest.
<service android:name=".GCMIntentService" />
To be compatible with GCMBroadcastReceiver, your GCMIntentService class must be a subclass of com.google.android.gcm.GCMBaseIntentService, and must contain a public constructor. The contents of this class will be discussed in the next section.
The following is an example containing the excerpts described above:
<manifest package="com.airbop.sample.gcm" ...>
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.airbop.sample.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.airbop.sample.gcm.permission.C2D_MESSAGE" />
<application ...>
<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="com.airbop.sample.gcm" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
</manifest>
You need to make a few small changes to your application in order to enable Google Cloud Messaging.
To register with GCM, your app just needs to call the following method and pass it your Google Project Number as a string:
GCMRegistrar.register(context, "<<your project number>>");
For example, if your project number was 827171612957 you could add the following code to your activity's onCreate() method to register the device with your GCM project:
// Verify that the device supports GCM
GCMRegistrar.checkDevice(this);
// Verify the application manifest contents - remove when ready to publish
GCMRegistrar.checkManifest(this);
// Check whether the device is already registered
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
final String googleProjectNumber = "827171612957";
// Not registered yet, so register the device with GCM
GCMRegistrar.register(this, googleProjectNumber);
} else {
Log.v(TAG, "Already registered");
}
The following callback methods should be overridden in your GCMIntentService class, so they can be called by the GCMBroadcastReceiver:
This method is called after the registration intent is received. The registration ID that was assigned to the device by GCM is passed as the second parameter.
The registration ID is what uniquely identifies the device on the GCM and AirBop servers.
At this point your application has registered with the GCM servers, but has not registered with AirBop. This is normally where you would send the registration information to the AirBop server and complete the registration process.
The following is an example of what your onRegistered method may look like:
@Override
protected void onRegistered(Context context, String registrationId) {
// Now that we have the registration id from GCM, we have
// everything we need to register with the AirBop servers
registerWithAirBop(registrationId);
}
This method is called after the device has been unregistered from GCM. If the device is still registered on the AirBop servers, it will need to unregister from AirBop well.
The following is an example of what your onUnregistered method may look like:
@Override
protected void onUnregistered(Context context, String registrationId) {
// If we are still registered with AirBop it is time to unregister
if (GCMRegistrar.isRegisteredOnServer(context)) {
unregisterFromAirBop(context, registrationId);
} else {
// We are not registered so there's nothing to do
}
}
This method is called when a message is sent from the AirBop server to GCM, and delivered to the device. The contents of the message are passed as extras in the intent.
AirBop's server console allows you to use either a predefined message format, or custom JSON for the data passed in the message.
When using AirBop's standard message format, the intent extras are defined as the following string values:
Below is an example of how to access the standard extras from the intent:
Bundle bundle = intent.getExtras();
if (bundle != null) {
String title = bundle.getString("title");
String message = bundle.getString("message");
String url = bundle.getString("url");
if ((title != null) && (message != null)) {
// Do something with the message data, such as call a function to show a notification
generateNotification(context, title, message, url);
}
}
Here is an example of what the JSON data looks like for a standard message:
{
"title": "Half Pint Special",
"message": "Humulous Ludicrous is on tap today only!",
"url": "http://www.somebeerpagesomewhere.com"
}
If you choose to send custom JSON data instead, all of the key-value pairs in the intent extras are up to you.
Here is an example of custom JSON data entered in AirBop's server console:
{
"team1": "FC Bayern Munich",
"team2": "Manchester City F.C.",
"score1": 2,
"score2": 0
}
This method is called when an error is returned by GCM when the device tries to register or unregister. This allows you to evaluate any problems that are encountered.
This method is called when a device tries to register or unregister, but the GCM servers are unavailable. The GCM library will automatically retry unless this optional method is overridden and returns false.
Generally you should only override this method if you want to display the message or cancel any further attempts.
Registering with the AirBop servers can be accomplished by posting the correct information to the following URL:
http://www.airbop.com/api/v1/register
When registering or unregistering with the AirBop servers the following headers are required:
"POST" + request_uri + AIRBOP_APP_KEY + timestamp + request.body + AIRBOP_APP_SECRETAn example implementation of this can be found in the AirBop-Client sample.
application/jsonor:
application/x-www-form-urlencoded
The GCM registration ID must be sent to AirBop in order to register the device with the AirBop servers. This information is sent to AirBop in the request body, along with several optional parameters.
The content type passed to the AirBop server controls what format the body is expected in. The preferred method is JSON (application/json).
Examples of how to construct the request body and post to the AirBop servers can be found in the AirBop-Client sample.
The following registration parameters are supported:
The registration ID received from the GCM servers, as described in the GCM Architectural Overview. This will be used to uniquely identify the device on the GCM and AirBop servers.
The ISO 3166-1 alpha-2 country code. This must be exactly two characters or it will be ignored.
A 50 character string that can be used to 'tag' or 'group' devices. You will be able to target devices based on this value when you send your message from the AirBop servers.
For example, if you wanted to differentiate device registrations from tablets vs. phones you could label them with either "phone" or "tablet" as appropriate. Then you would be able to target each group separately when sending push notifications.
The latitude value of the device. Stored as a float and accurate to one city block.
The longitude value of the device. Stored as a float and accurate to one city block.
The two character state or province code from the USA or Canada. This must be exactly two characters or it will be ignored.
If the location data is not sent, the server will attempt to fill in any missing data by performing an IP lookup on the device that posted the data. The location data that the AirBop server gets using this method will be quite accurate (99.5% at a country level and 90% at a state level), so you only need to provide your own data if you need greater accuracy, or want to provide a different location.
Here is an example of a JSON registration body as generated by the AirBop-Client sample:
{
"country":"CA",
"label":"AirBop Sample",
"lang":"en",
"lat":"49.897884",
"long":"-97.1351",
"reg":"XXXXXXXXXXXXXXXXXX",
"state":"MB"
}
Please see the Server Response Codes knowledge base article for more information about possible response codes from the AirBop server.
Unregistering from the AirBop servers can be accomplished by posting the correct information to the following URL:
http://www.airbop.com/api/v1/unregister
When unregistering from the AirBop servers, the same headers used when registering are required:
The GCM registration ID must be sent to AirBop in order to unregister the device from the AirBop servers. This is the only information that needs to be sent in the request body to AirBop.
As with registration, the content type passed to the AirBop server controls what format the body is expected in, and the preferred method is JSON (application/json).
Examples of how to construct the request body and post to the AirBop servers can be found in the AirBop-Client sample.
The following unregistration parameter is required:
The registration ID received from the GCM servers, as described in the GCM Architectural Overview. This will be used to uniquely identify the device on the GCM and AirBop servers.
Here is an example of a JSON unregistration body as generated by the AirBop-Client sample:
{
"reg":"XXXXXXXXXXXXXXXXXX"
}
The above article is a simplified overview of what's involved in integrating AirBop and Google Cloud Messaging into your Android application. For an in-depth discussion of GCM, you can reference the following articles in Google's developer documentation:
AirBop also provides a sample project which contains some helpful utility methods, and an example of best practices. You can use this both as an initial test of the service and as a future reference when implementing messaging in your own Android application. You can download the source code for the AirBop-Client sample app from GitHub.
Head back to the tutorials page for more information and walkthroughs - or just go ahead and sign up now to add AirBop to your Android app. It's free to get started and there's no obligation.
More Tutorials Sign Up Now