[This post is by Alexander Lucas, an Android Developer Advocate bent on saving the world 5 minutes. —Tim Bray]
With the addition of custom variables to the Mobile Analytics SDK for Android, it strikes me as a good time to cover something many of you might not have known was possible — using Google Analytics to easily track app usage. Using the mobile SDK is a handy way to get real data on how users interact with your Android apps. So today I'm going to explain how to track usage of your application with Google Analytics.
Prereqs Ahoy!
Before you take off running with this shiny new toy, there’s a few things you’ll need to set up first:
Download the mobile SDK. Download and installation instructions are available in the getting started section of the Mobile SDK docs, but the summarized version is:
Download the zip file from the download page
Put the libGoogleAnalytics.jar file in your project’s /libs directory
Be sure the following lines are in your AndroidManifest.XML file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />You’re going to need a Google Analytics account. Go to google.com/analytics and set up an account if you don’t already have one. Then set up a profile for your Android application. When you’re done you’ll see a javascript snippet to insert into your “site”. Copy the part that looks like UA-XXXXXXX-X. You’ll use this in the Android application to tell Analytics which profile the data is being sent for.
Get Tracking
Previous Google Analytics users are going to find a lot of this familiar. In fact, we’ve made a point of keeping the interface as familiar as possible.
First, get your tracker object, and initialize it using the UA code for the Analytics profile you want to track. It makes the most sense to do this in the onCreate()
method for your activity main, so it only fires when your application starts up.
GoogleAnalyticsTracker tracker;
protected void onCreate(Bundle savedInstanceState) {
...
tracker = GoogleAnalyticsTracker.getInstance();
tracker.start(“UA-1234-1”, this);
…
}
The mobile SDK provides support for the 3 main types of data sent to the Google Analytics servers: Pageviews, events, and custom variables.
Pageviews
A pageview is a standard means to measure traffic volume to a traditional website. Given that this is going into an Android app and not a website, it’s going to be up to you to decide what a “pageview” means. Depending on the type of app, each Activity or different views within the same activity (for instance, different tabs within a TabActivity) could count as a pageview.
Whenever you want to trigger a pageview, call the trackPageView()
method. It only takes one parameter, the URL you want a pageview counted towards.
tracker.trackPageView("/HomeScreen");
Pageviews make the most sense as full screen transitions, which in most cases will mean “one pageview per Activity.” Therefor it makes the most sense to put the call to trackPageView in the onCreate()
method for each activity in your application. An exception would be if you were using a TabActivity, or other scenario where there were multiple full-screen transitions which all occurred within the same Activity, and conceptually mapped to seperate full-screen “pages” being viewed.
Events
In Analytics, events are designed to track user interaction to that doesn’t map to pageviews, like hitting play/pause/stop in a multimedia app. This maps very well to Android usage — Any form of interaction, from hitting certain buttons to adding/removing data from the datastore, can be tracked using Events.
Events are a little more complicated than pageviews, but just slightly. Instead of 1 parameter, you have 4: Category, Action, Label (optional), Value (optional).
To see how to make use of these, let’s imagine you had a media player application, and wanted to track how many times play, pause, and stop were clicked. The code would look like this:
playButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
...
tracker.trackEvent(
"Media Player", // Category
"Click", // Action
"Play", // Label
0); // Value
}
});
pauseButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
...
tracker.trackEvent(
"Media Player", // Category
"Click", // Action
"Pause", // Label
0); // Value
});
stopEventButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
...
tracker.trackEvent(
"Media Player", // Category
"Click", // Action
"Stop", // Label
currentVideo.getPositionInSeconds()); // Value
});
myMediaPlayer.setFinishedListener(new FinishedListener() {
@Override
public void onFinished(View v) {
...
tracker.trackEvent(
"Media Player", // Category
"Video Finished", // Action
"Stop", // Label
currentVideo.getLengthInSeconds()); // Value
});
Remember that in the Google Analytics web interface, this data is displayed hierarchically — For instance, if you click on Categories in the left nav, and then on “Media Player”, you’ll see a list of all the different possible values of “Action” which have happened in the “media Player” category. Clicking on “Click” will show all the labels which were sent in the Media Player category with an action of “Click”.
The 4th parameter, “value”, is optional, and behaves differently from the others. It’s meant to be cumulative; In this example, I’m sending the amount of video watched when a video is either stopped or allowed to finish. This is aggregated server-side, and when I go to look at my data I’ll be able to see the total time people have spent watching videos using my application.
Custom Variables
The new hotness! Custom variables are name-value pair tags that you can insert in your tracking code in order to refine Google Analytics tracking. The easiest way to think of this is as meta-data accompanying your pageviews and events. Using this metadata, it becomes easy to split off and look at segments of your data, much the same way you use labels in Gmail. One Android-specific example would be to have a “AppType” status with “Full” or “Lite” depending on whether the user has the full version of the app or not. You could then use the Analytics web interface to look at only the “Lite” users, and see how their usage / userbase differs from the “Full” segment. Custom variables are a ridiculously powerful analytical tool, but they’re also a deep topic. I heartily recommend giving the docs a once-through before implementing them in your Android application. Especially make sure to read the section on scoping. Twice. I’m mean it... I’ll wait.
There are 4 parameters in a custom variable: Index (1 to 5 inclusive), Name, Value, and Scope (Optional, defaults to Page Scope).
The place in your code where setCustomVar()
will be called depends largely on what scope that variable will be:
Visitor scope: Call once the first time your application is run on a device. Don’t create any custom variables at the same index, or they will overwrite the first one. Useful for sending data about which version of the app is being used, what kind of phone, lite vs full version of the app, or anything that won’t change during the lifetime of the installation of that application.
Session scope: Call once at the beginning of every Activity startup. Will apply to all pageviews and events for the lifecycle of the activity, unless a different custom variable is created at the same index.
Page scope: Call right before trackEvent or trackPageView that the custom variable should apply to, every time that method is called. If no scope is specified, this is the default.
The call to set a custom variable will look like the following:
// Scopes are encoded to integers: Visitor=1, Session=2, Page=3
tracker.setCustomVar(1, "Navigation type", "Button click", 3);
Choose a Dispatch Mode
In order to optimize for battery life, a request isn’t actually sent out to the server every time you fire a pageview or custom variable. Instead, all the pageviews, events, and their associated custom variables are stored in a local SQLITE database until they’re dispatched as a group to the server. You can set this up to happen one of two ways: Either have the dispatch occur automatically every n seconds, or manually when you call “dispatch” in code. The mode is chosen when you call the start method on your tracker.
Manual dispatch looks like this:
// No time increment sent as a parameter
tracker.start(“UA-1234-1”, this);
…
// Call this when you want to send the entire event queue to the server
tracker.dispatch();
The timed automatic dispatch looks similar, but sends an extra parameter (the number of seconds between dispatches). In timed dispatch, you never have to manually call dispatch.
// Dispatch all queued pagevies/events every 300 seconds (5 minutes)
tracker.start("UA-YOUR-ACCOUNT-HERE", 300, this);
It’s important to remember that Google Analytics uses the timestamp for when it receives your data, not when the actual pageview/event occurred. This can potentially lead to inaccurate Analytics data, since events can be sent on different days than when they occurred, so take care to dispatch regularly.
The end result
Let’s go back to that onCreate()
method we used to instantiate the tracker earlier, and see what it looks like with all the pieces in place:
GoogleAnalyticsTracker tracker;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tracker = GoogleAnalyticsTracker.getInstance();
tracker.start(“UA-1234-1”, this);
if(isFirstTimeRunningApplication()) {
tracker.setCustomVar(1, “App Type”, “Demo”, 1);
}
tracker.trackPageView("/HomeScreen");
…
}
How to look at all this data
There are two ways you can approach this. First, Google Analytics has a pretty snazzy web interface, which does a very good job of surfacing useful information for you. If you’re new to Analytics and don’t really know what you’re looking for yet, the web interface is a great way to explore your data and understand your users.
If you already have a strong idea of the questions you want to ask (app usage across versions of the Android platform, growth rates, time-in-app per demo user vs full user, how many people beat level 3 on their first try, etc), and just want to automate the asking, Google Analytics also has a swanky data export API, with client libraries to facilitate the querying of your data in Java, Python, JavaScript, and C#.
Abiding by the TOS
Google Analytics comes with its own TOS, and it’s important to read and abide by it. The important bit, especially since this will be used inside Android applications, is that you cannot send personally identifying information to Analytics servers. This is a big deal. It means, for instance, that a visitor-level custom variable cannot contain a phone number, first name, or email address. Less intuitively, but still important, it means that if this application is a client to a web application (say, CRM software or a shopping site), you also cannot store information in Analytics which can be combined with your own backend software to identify the user, such as user ID or a transaction ID identical to the one stored on your web backend.