Up, up, and away with Urban Airship


Airship illustration by Alan Gutierrez

© Alan Gutierrez

Update

I have gotten a lot of feedback from this post. I am a freelance Android developer. If you get stuck or simply don’t want the headache of configuring push notifications. I can be hired.

Forward

This tutorial is for using Urban Airship’s Android push notifications service. They offer two different methods for enabling push notifications. One via their in house helium service, and the other using Google’s Cloud to Device Messaging(C2DM) framework. This tutorial will focus on the Cloud to Device Messaging.

Prerequisites & Assumptions

  • Android device running OS 2.2 or above.
  • You will need an account with Urban Airship and to have downloaded the library. This tutorial is using version 1.0.1.
  • You will also need to sign up for google’s Cloud to Device Messaging.
  • Python for using a helper script provided by Urban Airship.
  • While not mandatory, I will be using Eclipse for my dev environment and assume that you are comfortable creating android projects in Eclipse.

Step 1 Obtain a C2DM Authorization Token

screen shot of clientauth.py output

Helpful tool for getting the C2DM authorization code

  • On your computer go to where you downloaded the Urban Airship Android Client Library Zip
  • Unzip the Client Library
  • inside there is a tools directory(ua-android-lib-latest/tools)
  • Run the clientauth.py script
  • When you see “C2DM Google Account” enter the email address that you used to sign up for C2DM
  • Enter your password for the account


If everything goes well you should see something similar as pictured.

  • Copy the token value, we will need it in step 2

Step 2 Add a new application to your Urban Airship Apps page

Screen shot of urban airships add application page

Note the important fields

  • Login in to your Urban Airship account
  • Go to your apps page
  • Fill out an application name
  • Check the box that says Push Notification Support
  • Go down to the Android section
  • For Android Package field is the package name you use in your application. I am going to use com.example.NotifyMe
  • Paste the C2DM Authorization Token from Step 1 into the C2DM Authorization Token field
  • Press the Create your app button


You will be taken to a details screen for the app. The screen will have information that you will need for step 4(developmentAppKey, and developmentAppSecret)

Notes Urban Airship makes it easy to test notifications in a development setting before sending them live by allowing you to create a development key/secret in addition to the production key/secret. This allows you to validate a message on test devices before sending it to live devices.

Step 3 Create an Eclipse project

  • Name your project whatever
  • Make sure that the package name matches the package name from Step 2

Step 4 Create an airshipconfig.properties file

screenshot of airshipconfig.properties

airshipconfig.properties that should be set

  • In the assets directory create an airshipconfig.properties file
  • Copy and paste the following lines into your config

developmentAppKey = <Ontained from step 2>
developmentAppSecret = <Obtained from step 2>
productionAppKey = Your Production App Key
productionAppSecret = Your Production App Secret
inProduction = false
transport = c2dm
c2dmSender = 
iapEnabled = false

Notes my app kept crashing on launch, until I added iapEnabled = false
This is for in app purchasing.

Step 5 Add a reference to the library

Screen shot of adding urban airship to Eclipse project

Add the Urban Airship library to our project

  • In Eclipse right click the project folder
  • Go to File > Properties
  • Click Java Build Path in the left pane
  • Click the libraries tab
  • Click the “Add External JARs…” button
  • Select the Urban Airship jar that you downloaded(mentioned in the perquisites)
  • Click Ok to dismiss the properties screen

Step 6 Edit the AndroidManifest.xml

There are lots of lines that simply have to be copied in order to get push notifications to work. This is almost a direct copy of what is specified in the documentation.

  • Copy the following xml into the application tag.
        <!-- REQUIRED -->
        <receiver android:name="com.urbanairship.CoreReceiver">
            <!-- REQUIRED IntentFilter - For Helium and Hybrid -->
            <intent-filter>
              <action android:name="android.intent.action.BOOT_COMPLETED" />
              <action android:name="android.intent.action.ACTION_SHUTDOWN" />
            </intent-filter>
        </receiver>

        <!-- REQUIRED for C2DM and Hybrid -->
        <receiver android:name="com.urbanairship.push.c2dm.C2DMPushReceiver"
                android:permission="com.google.android.c2dm.permission.SEND">
          
		<!-- Receive the actual message -->
          <intent-filter>
              <action android:name="com.google.android.c2dm.intent.RECEIVE" />
              <category android:name="com.example.notifyme" />
          </intent-filter>
          <!-- Receive the registration id -->
          <intent-filter>
              <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
              <category android:name="com.example.notifyme" />
          </intent-filter>
        </receiver>

        <!-- REQUIRED -->
        <!-- The 'android:process' parameter is optional. Set it to a value starting
            with a colon (:) to make it run in a separate,
            private process -->
        <service android:name="com.urbanairship.push.PushService"
                android:process=":com.urbanairship.push.process"/>

        <!-- OPTIONAL, if you want to receive push, push opened and registration completed intents -->
        <!-- receiver android:name="com.urbanairship.push.sample.IntentReceiver" /-->
        <receiver android:name=".IntentReceiver" />

  • Replace the name attributes with the correct package name in the category tags
  • Make sure to pay attention to the name given to the receiver on the last line
  • Copy the following xml into manifest tag
    <!-- REQUIRED -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.android.vending.BILLING" />

    <!-- REQUIRED for C2DM  -->
    <!-- Only this application can receive the messages and registration result -->
    <permission android:name="com.example.notifyme.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
    <uses-permission android:name="com.example.notifyme.permission.C2D_MESSAGE" />

    <!-- This app has permission to register and receive message -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

  • Add “android:name=”.NotifyMeApplication” to the application tag

Note you can change the value to whatever you want, as long as it matches up with the class name in step 8

Step 7 Create a broadcast receiver

Screenshot of broadcast receiver

Broadcast Receiver for push notifications

  • Create a class that extends broadcast receiver
  • Make sure the class name matches that from android manifest


Here we will get the action from the intent in order to determine what the intent is for. There are two different actions that are used in this example. They are self explanatory:

  • PushManager.ACTION_PUSH_RECEIVED (notification was received on the device)
  • PushManager.ACTION_NOTIFICATION_OPENED (notification was selected from the system notifications)
public class IntentReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context aContext, Intent aIntent) {

		String action = aIntent.getAction();
		if (action.equals(PushManager.ACTION_NOTIFICATION_OPENED)) {
			// user opened the notification so we launch the application

                        // This intent is what will be used to launch the activity in our application
			Intent lLaunch = new Intent(Intent.ACTION_MAIN);

                        // Main.class can be substituted any activity in your android project that you wish
                        // to be launched when the user selects the notification from the Notifications drop down
			lLaunch.setClass(UAirship.shared().getApplicationContext(),
					Main.class);
			lLaunch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        // copy the intent data from the incoming intent to the intent
                        // that we are going to launch
			copyIntentData(aIntent, lLaunch);

			UAirship.shared().getApplicationContext().startActivity(lLaunch);

		} else if(action.equals(PushManager.ACTION_PUSH_RECEIVED)){
			// push notification received, perhaps store it in a db

		}

	}

Step 8 Extend the Application class

  • Create a class that extends the application class
  • Override the onCreate method
  • Add the following lines:

public class NotifyMeApplication extends Application{

	@Override
	public void onCreate() {
		super.onCreate();
                UAirship.takeOff(this); // always needs to be called when starting an application

                // even though we call takeoff push notifications are disabled by default
                // you have to explicitly turn them on like so
                PushManager.enablePush();
                
                // let the push manager know about our intent receiver
                PushManager.shared().setIntentReceiver(IntentReceiver.class); // name must match broadcast receiver from step 7
                
                // set some preferences for sounds and vibration
                PushPreferences prefs = PushManager.shared().getPreferences();
                prefs.setSoundEnabled(true);
                prefs.setVibrateEnabled(true);

                // apid is a unique identifier for a particular device
                String lPushId = prefs.getPushId();
                Logger.info("My Application onCreate - App APID: " + lPushId);

This last line is important because it allows us to send message targeted to individual devices

Step 9 Discover the APID(Android Push ID)

Search Log Cat for APID

Search Log Cat for the APID

The APID is an Urban Airship id that uniquely identifies an Android device. This allows messages to be sent to specific devices.
  • Run the application
  • Open logcat
  • Find the APID


Note the first time running may give an APID that is null, just run the app a second time and you should be good to go

  • Copy the APID so that we can send messages to this individual device

Step 10 Send test messages from Urban Airship site

Screenshot of test push notification from Urban Airship's site

Test a push notification on urban airships site

  • Log back into your Urban Airship account
  • Go to your apps page
  • Click on the visit application button of the app you had created in step 2
  • Click the Push button
  • Click the “Test Push Notifications” text
  • Click the Android tab
  • Paste the APID from step 9 into the Apid field
  • Add an alert field
  • Add text to extra key and value fields
  • Note you can just modify the payload if you’d like

  • Click Send it!
  • Screenshot of notification displayed on Android OS

    Your application icon will be displayed in the status bar

    Screenshot of notification pulldown

    Notification will be listed in the Notifications Pull Down Menu

    If everything went well you should get a notification on your android phone.

Step 11 Get the values from the intent

At this point the notification will have launched your activity. While that is useful you want access to the data that was actually pushed to that activity. This can be done via Intent.getStringExtra(“name of extra string”).

Note that in the case of trying to get the Alert string the actual string is “com.urbanairship.push.ALERT”
so you’d do Intent.getStringExtra(“com.urbanairship.push.ALERT”).

Debugging tips

  • If you aren’t getting notifications make sure to check the apps error console on the Urban Airship site.
  • Also check to make sure you explicitly turned notifications on in step 6(PushManager.enablePush())

Additionally

If you’d like to send your own notifications from the web here is some sample php code for pushing info to Urban Airships site.

Big note! You will need your Application Secret and your Application _Master_ Secret
The documentation was very lacking on specifying that the master key was needed as opposed to the application secret.

Comments 9

  1. Hi, Great article!

    You say I will need “Application Secret and your Application _Master_ Secret” at what point do i need the _Master_ secret?

    Cheers

  2. Hi

    Step 1 cannot be implemented

    >>Go to the Urban Airship download tools directory(ua-android-lib-latest/tools)

    no such a directory on Urban Airship site

  3. >> no such a directory on Urban Airship site

    discard
    it’s about tools folder in UA lib intallation folder
    my fault 🙂

  4. the sources got errors on compilation

    Main.class and copyIntentData cannot be resolved in IntentReceiver

  5. Hi. Gr8 article.
    Main.class represents your activity that will open after uses selects notification.
    Still can not figure out what does copyIntentData works? Just something like lLaunch.setData(aIntent.getData()) or what?

    thx

  6. HI, this wonderful article, i am receiving notifications, but the problem is that i don’t want notification shows in notification bar when application is foreground. Please can you help me to stop notification to display in notification bar when application is foreground.

  7. Hey thanks for the article. It did help me a lot but I am stuck at one part. My Logcat gives me an error saying that : Failed to register APID
    My internet connection is working fine and I am testing it out on the emulator. Any ideas on what might be going wrong ?

Leave a Reply

Your email address will not be published. Required fields are marked *