App Tracking – Part II

We’ll put some meat to the bone today and provide a bit of sample code and guidance around tracking a mobile app.


As we said in Tracking Mobile Apps, you need to download the AMC library for your target OS and include that into your project.

We’ll build the sample on Android (because we don’t know iOS very well), so the first step is to download the Android library from and add the admsAppLibrary.jar file to our project in eclipse.

Android Project with JAR
Make sure your app has the right permissions:

  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

We won’t go into detail about any of this because the documentation has it covered already and it really is not that difficult. With one exeption:

Lifecycle Metrics

The lifecycle metrics that were introduced with v3.x of the libraries are worth a separate look.

From the point of view of a developer, they are extremely simple — they just work out of the box as long as you tag the onPause and onResume callbacks for all your Activities, as the documentation suggests.

The lifecycle metrics provide your friendly marketer with a bunch of useful metrics about installs, upgrades, recency and frequency of usage, session length, crashes and so on.

When your friendly marketer sends out an email, driving people to download your app, they can add the usual URL parameters which Google Play recognises. The great thing is that Google Play actually passes these on to the app!

Lifecycle metrics include the campaign parameters, so your marketer can run an analysis on his email and get all the data you collect. In essence, your friendly marketer gets a full end-to-end analysis for their channels and Android apps.

This is currently only possible with Google Play. Apple has unfortunately not provided any similar mechanism for iTunes so far. Let’s hope they will at some point.

Tagging a “Page”

We’re using Android as the example here, so when we’re talking about tagging a “page”, we really mean tagging an Activity. On iOS, we would be tagging a View, of course.

An Activity has a relatively involved lifecycle.

In terms of tracking the Activity, we can probably simplify things and hook into the last callback before the Activity is running (which is onResume()) and the first callback when the Activity leaves the running state (which is onPause()).

It makes sense to treat onResume() like the loading of a web page. Everything you would track on a web page (e.g. s.pageName), you should track in onResume().

On top of that, you can make a marketers dream come true and track when people leave a page. That’s what onPause() is equivalent to, of course.

You could even track more detailed than that, and in some cases it might make sense — differentiating between onPause() and onStop() could be useful if your app does stuff in the background, for example play music.

On iOS, the lifecycle is simpler, but the idea is the same: find the callbacks closest to running state and add tracking to those callbacks.

Thinking about onResume() as page load and onPause() as leaving the page leads to a simple rule: use tracking calls in onResume() that cause a Page View. Examples are startActivity(), trackAppState() or simply track().

Conversely, use a method that does not log a Page View in onPause(). Examples are stopActivity(), trackEvent() or trackLink().

What do we Track?

Now that you know where to add the tracking, the next question is of course what should you track?

Let’s look back at the simple example we used to explain basic tracking on a web site. We proclaimed that reasonable tracking should at least contain s.pageName and at least an event in

That can easily be transferred to mobile apps, of course.

Firstly, we simply map the “page” concept to Activities. So when an activity is launched, we assign the name of the activity as the name. This might be “Main Activity”, “Settings Panel”, or maybe “Map View”.

One thing here: please do not name the Activities yourself! Ask your friendly marketer instead, or maybe the app designer. It is pretty important that everyone is using the same name and for that the name must be good. (Yes, our examples are not that good.)

Depending on how we decided to use events, each Activity might also be tagged with one or more events, just like our pages on the web.


We reckon that for any meaningful tracking in your apps, you should add your own (static) helper methods to the TrackingHelper class.

For example, you should have a custom event that fires on start of every Activity and is therefore similar to a custom Page View metric on the web. You would also have a specific event for the main Activity or Activities of your app. Those should be added to your custom methods.

I guess what we’re saying is: create a custom tracking method in TrackingHelper for each Activity (or View on iOS) and use those in the onResume() callback for the Activity in question.

Tracking User Actions

Say your app allows sharing of content, links or something else. Your friendly marketer will want to know how often users make use of this functionality, so you’ll ideally want to tag it. This is very similar to tracking actions on a web page.

Programmatically, you’ll use Context.startActivity() or Context.startActivityForResult() to either invoke a specific Activity or one that fullfills the requirements and is chosen by Android and/or the user.

The straight-forward part here is tracking when the user starts the process of sharing — just create a static method in the TrackingHelper class for tracking this and call it before you call Context.startActivity() or Context.startActivityForResult().

It is somewhat harder to track whether they actually ended up sharing or not.

If your app uses Context.startActivityForresult(), you can add tracking to your implementation of the onActivityResult() callback.

If you use Context.startActivity() instead, you could try and play around with flagging this and detecting the flag in onResume() when control comes back to your Activity, if it does.

And what would you track?

Well, as on the web, you’d highly likely track a custom event along with some data about what the action was. Example:

Presuming your app allows people to share links and notes, you’d want to set a custom event when the share functionality is invoked by the user, along with a conversion variable (an eVar) that specifies whether a link or note were going to be shared. Like so:

  measure.setEvar(3, "note");
  measure.trackLink(null, "o", "Sharing started", null, null);

If you are using context Data variables, the tracking might look like this:

  Hashtable<String, Object> contextData = new Hashtable<String, Object>();
  contextData.put("shareType", "note");
  measure.trackEvents("event15", contextData);

The methods trackEvents() and trackLink() are the equivalents of the method in Javascript-based tracking. The trackEvents() method is newer and easier to use for those who use context data variables.

Tracking Eco System

Just as an FYI:

It is technically possible for you to do some research about the devices that your app is installed on.

Using queryIntentActivities(), queryIntentServices() or queryBroadcastReceivers() (all in PackageManager), you can find out a lot about what apps and capabilities your users have installed.

Build a utility method somewhere that runs those, then send the (abbreviated) results.

You could use this to look for capabilites (“how many of our users have a twitter client installed?”, “how many ACTION_SEND-capable apps do our users have?”) or even competitors (“how many have software xyz?”).

As we said, this is technically possible. Is it desirable to do it? Take into account that most users do not like being spied upon!

3 thoughts on “App Tracking – Part II

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.