Android Integrating Google Analytics V4

Have you ever wondered how to track your android user activity in real time? If yes, well here is the solution you are looking for. User activity tracking can be done using any good analytics tool. There are lot of tools out there like Mixpanel, Flurry etc., to track the user activity in real time but none of them are totally free. Google analytics is a powerful service which comes with great features like real time user count, event tracking, geo tracking, error & crash reporting and lot more and yet it is completely free.

In this article we are going to learn how to integrate Google Analytics in your android app. Although Google Analytics provides huge number of analytical features, we are going to cover only the essential modules necessary for every android app.

android google analytics integration tutorial

Below is the screenshot of real time users on one of the apps I have worked on.

android-google-analytics-real-time-users

1. Creating Google Analytics Property

Google Analytics tracking ID identifies the analytics property for which mobile tracking is enabled. Follow the below steps to get your property tracking ID.

1. Sign in to your Google Analytics account.

2. Select the Admin tab.

3. In the ACCOUNT dropdown, click on Create new account. (Or select the property if you created one already)

4. Select Mobile App in the new property form.

5. Enter the App Name.

6. Select Industry Category & Report Time Zone and click on Get Tracking ID.

7. In the next screen you will be shown your property Tracking ID.

The tracking ID should look like UA-XXXXXXXX-X. Note this tracking ID somewhere as we’ll need this in our android project.

android-creating-google-analytics-property

2. Creating Android Project

Once you got the tracking ID, let’s start the android project. We’ll create an android app with simple user interface to test the each module.

1. In Android Studio, create a new project by navigating to File ⇒ New Project and fill all the required details. When it prompts to select a default activity, select Blank Activity and proceed.

2. Turn your app into Material Design supported if you want to. But this step is optional.

3. Create two packages named activity and app to keep the project organized. Move the MainActivity.java under activity package.

4. Open strings.xml located under res ⇒ values and add below string values.

<resources>
    <string name="app_name">Google Analytics</string>
    <string name="action_settings">Settings</string>
    <string name="title_activity_second">Second Activity</string>
    <string name="toast_track_exception">Exception is recorded. Check the Crashes and Exceptions on Google Dashboard!</string>
    <string name="toast_app_crash">The app will crash now! Check the Crashes and Exceptions on Google Dashboard!</string>
    <string name="fragment_footer">Fragment is loaded! Check the screen view on Google Analytics Dashboard.</string>
    <string name="msg_instructions">Click on each button to see the appropriate tracking on Google Analytics</string>
    <string name="btn_second_screen">Second Screen</string>
    <string name="btn_send_event">Track Event</string>
    <string name="btn_exception_tracking">Track Exception</string>
    <string name="btn_app_crash">Track App Crash</string>
    <string name="btn_load_fragment">Fragment Tracking</string>
</resources>

5. Open colors.xml located under res ⇒ values and add below color resources. If you don’t see colors.xml, create a new file with the name.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#FF6D00</color>
    <color name="colorPrimaryDark">#FF6D00</color>
    <color name="textColorPrimary">#FFFFFF</color>
    <color name="windowBackground">#FFFFFF</color>
    <color name="navigationBarColor">#000000</color>
    <color name="colorAccent">#FFD180</color>
    <color name="btnBackground">#e7e7e7</color>
</resources>

2.1 Adding Google Analytics

Now follow below steps to add the google analytics to your project.

6. Open build.gradle located under app folder and add google analytics dependency com.google.android.gms:play-services-analytics:7.3.0

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile 'com.google.android.gms:play-services-analytics:7.3.0'
}

7. Create a folder named xml under res. Inside xml folder, create an xml file named app_tracker.xml and add below analytics configuration.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- End current session if app sleeps for a period of time -->
    <integer name="ga_sessionTimeout">300</integer>

    <!-- Enable automatic Activity measurement -->
    <bool name="ga_autoActivityTracking">true</bool>

    <!--  The property id associated with this analytics tracker -->
    <string name="ga_trackingId">UA-58121605-1</string>

    <string name="ga_sampleFrequency">100.0</string>

    <bool name="ga_reportUncaughtExceptions">true</bool>

    <!--
      See Project Structure -> Analytics -> Google Analytics -> Learn More
      to learn more about configuring this file.
    -->
</resources>

Make sure that you replaced the ga_trackingId with your tracking ID which we retrieved in above section. This step is very important, otherwise you won’t be able to see the stats on your analytics dashboard.

8. Under app package, create a class named AnalyticsTrackers.java with the below code.


import android.content.Context;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.Tracker;

import java.util.HashMap;
import java.util.Map;

import info.androidhive.googleanalytics.R;

/**
 * A collection of Google Analytics trackers. Fetch the tracker you need using
 * {@code AnalyticsTrackers.getInstance().get(...)}
 * <p/>
 * This code was generated by Android Studio but can be safely modified by
 * hand at this point.
 * <p/>
 * TODO: Call {@link #initialize(Context)} from an entry point in your app
 * before using this!
 */
public final class AnalyticsTrackers {

    public enum Target {
        APP,
        // Add more trackers here if you need, and update the code in #get(Target) below
    }

    private static AnalyticsTrackers sInstance;

    public static synchronized void initialize(Context context) {
        if (sInstance != null) {
            throw new IllegalStateException("Extra call to initialize analytics trackers");
        }

        sInstance = new AnalyticsTrackers(context);
    }

    public static synchronized AnalyticsTrackers getInstance() {
        if (sInstance == null) {
            throw new IllegalStateException("Call initialize() before getInstance()");
        }

        return sInstance;
    }

    private final Map<Target, Tracker> mTrackers = new HashMap<Target, Tracker>();
    private final Context mContext;

    /**
     * Don't instantiate directly - use {@link #getInstance()} instead.
     */
    private AnalyticsTrackers(Context context) {
        mContext = context.getApplicationContext();
    }

    public synchronized Tracker get(Target target) {
        if (!mTrackers.containsKey(target)) {
            Tracker tracker;
            switch (target) {
                case APP:
                    tracker = GoogleAnalytics.getInstance(mContext).newTracker(R.xml.app_tracker);
                    break;
                default:
                    throw new IllegalArgumentException("Unhandled analytics target " + target);
            }
            mTrackers.put(target, tracker);
        }

        return mTrackers.get(target);
    }
}

9. Create a class named MyApplication.java under app package. This class extends from Application class which needs to be added in AndroidManifest.xml.

This call contains below important methods.

trackScreenView() – Function to track screen view (Activity or Fragment).

trackException() – Function to track exceptions using try & catch.

trackEvent() – Function to track event.


import android.app.Application;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.StandardExceptionParser;
import com.google.android.gms.analytics.Tracker;

/**
 * Created by Ravi on 13/08/15.
 */
public class MyApplication extends Application {
    public static final String TAG = MyApplication.class
            .getSimpleName();

    private static MyApplication mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;

        AnalyticsTrackers.initialize(this);
        AnalyticsTrackers.getInstance().get(AnalyticsTrackers.Target.APP);
    }

    public static synchronized MyApplication getInstance() {
        return mInstance;
    }

    public synchronized Tracker getGoogleAnalyticsTracker() {
        AnalyticsTrackers analyticsTrackers = AnalyticsTrackers.getInstance();
        return analyticsTrackers.get(AnalyticsTrackers.Target.APP);
    }

    /***
     * Tracking screen view
     *
     * @param screenName screen name to be displayed on GA dashboard
     */
    public void trackScreenView(String screenName) {
        Tracker t = getGoogleAnalyticsTracker();

        // Set screen name.
        t.setScreenName(screenName);

        // Send a screen view.
        t.send(new HitBuilders.ScreenViewBuilder().build());

        GoogleAnalytics.getInstance(this).dispatchLocalHits();
    }

    /***
     * Tracking exception
     *
     * @param e exception to be tracked
     */
    public void trackException(Exception e) {
        if (e != null) {
            Tracker t = getGoogleAnalyticsTracker();

            t.send(new HitBuilders.ExceptionBuilder()
                            .setDescription(
                                    new StandardExceptionParser(this, null)
                                            .getDescription(Thread.currentThread().getName(), e))
                            .setFatal(false)
                            .build()
            );
        }
    }

    /***
     * Tracking event
     *
     * @param category event category
     * @param action   action of the event
     * @param label    label
     */
    public void trackEvent(String category, String action, String label) {
        Tracker t = getGoogleAnalyticsTracker();

        // Build and send an Event.
        t.send(new HitBuilders.EventBuilder().setCategory(category).setAction(action).setLabel(label).build());
    }

}

10. Open AndroidManifest.xml and do the below changes.

> Add MyApplication to <application> tag.

> Add INTERNET and ACCESS_NETWORK_STATE permissions.

> Add the receivers and services mentioned below. These are optional, but recommended for accurate results.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.googleanalytics">

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

    <application
        android:name=".app.MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".activity.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!--
          Optionally, register AnalyticsReceiver and AnalyticsService to support background
          dispatching on non-Google Play devices
        -->
        <receiver
            android:name="com.google.android.gms.analytics.AnalyticsReceiver"
            android:enabled="true">
            <intent-filter>
                <action android:name="com.google.android.gms.analytics.ANALYTICS_DISPATCH" />
            </intent-filter>
        </receiver>

        <service
            android:name="com.google.android.gms.analytics.AnalyticsService"
            android:enabled="true"
            android:exported="false" />

        <!--
             Optionally, register CampaignTrackingReceiver and CampaignTrackingService to enable
             installation campaign reporting
        -->
        <receiver
            android:name="com.google.android.gms.analytics.CampaignTrackingReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="com.android.vending.INSTALL_REFERRER" />
            </intent-filter>
        </receiver>

        <service android:name="com.google.android.gms.analytics.CampaignTrackingService" />
    </application>

</manifest>

Congratulations! your Google Analytics setup is done. Now if you run the app, you should see one user on Google Analytics dashboard. You won’t be able to see the user on the dashboard instantly due to slight delay in google analytics. You will have to wait for 2-3 mins to see the users on the dashboard. If no users are displayed, make sure that you followed the above steps correctly.

android-google-analytics-tracking-activity

Before start discussing about the modules, we’ll do the changes needed to create the interface to demonstrate them.

11. Under res ⇒ layout, create an xml layout named toolbar.xml and add below code.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="2dp"
    local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    local:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

12. Open the layout of your main activity (activity_main.xml) and do the below changes. This layout contains few buttons to invoke different analytics events.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    tools:context=".MainActivity">

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"/>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/toolbar"
        android:orientation="vertical">

        <TextView
            android:layout_width="fill_parent"
            android:gravity="center_horizontal"
            android:padding="10dp"
            android:layout_height="wrap_content"
            android:text="@string/msg_instructions" />

        <Button android:id="@+id/btnSecondScreen"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/btnBackground"
            android:text="@string/btn_second_screen"
            android:textAllCaps="false"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:textColor="#797979"
            android:layout_gravity="center_horizontal"
            android:elevation="2dp"
            android:layout_marginTop="20dp"/>

        <Button android:id="@+id/btnSendEvent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/btnBackground"
            android:text="@string/btn_send_event"
            android:textAllCaps="false"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:textColor="#797979"
            android:layout_gravity="center_horizontal"
            android:elevation="2dp"
            android:layout_marginTop="20dp"/>

        <Button android:id="@+id/btnException"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/btnBackground"
            android:text="@string/btn_exception_tracking"
            android:textAllCaps="false"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:textColor="#797979"
            android:layout_gravity="center_horizontal"
            android:elevation="2dp"
            android:layout_marginTop="20dp"/>

        <Button android:id="@+id/btnAppCrash"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/btnBackground"
            android:text="@string/btn_app_crash"
            android:textAllCaps="false"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:textColor="#797979"
            android:layout_gravity="center_horizontal"
            android:elevation="2dp"
            android:layout_marginTop="20dp"/>

        <Button android:id="@+id/btnLoadFragment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/btnBackground"
            android:text="@string/btn_load_fragment"
            android:textAllCaps="false"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:textColor="#797979"
            android:layout_gravity="center_horizontal"
            android:elevation="2dp"
            android:layout_marginTop="20dp"/>

    </LinearLayout>

    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />


</RelativeLayout>

13. Open MainActivity.java and do the below changes. Here we are declaring few buttons those are defined in the xml layout.

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import info.androidhive.googleanalytics.R;
import info.androidhive.googleanalytics.app.MyApplication;

public class MainActivity extends AppCompatActivity {

    private static String TAG = MainActivity.class.getSimpleName();

    private Toolbar mToolbar;

    private Button btnSecondScreen, btnSendEvent, btnException, btnAppCrash, btnLoadFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        btnSecondScreen = (Button) findViewById(R.id.btnSecondScreen);
        btnSendEvent = (Button) findViewById(R.id.btnSendEvent);
        btnException = (Button) findViewById(R.id.btnException);
        btnAppCrash = (Button) findViewById(R.id.btnAppCrash);
        btnLoadFragment = (Button) findViewById(R.id.btnLoadFragment);

        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);

        /**
         * Launching another activity to track the other screen
         */
        btnSecondScreen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }
}

Now if you run the app, it should look like below.

android-google-analytics-app-tutorial

2.1 Tracking Activity

Tracking activity view is very simple. It can be done in two ways. You can choose whichever way suits to your app requirement.

⇒ Automatic Screen Tracking

If you set ga_autoActivityTracking to true in app_tracker.xml, all the activities tracking will be automatically. However if you want to keep a name to screen, you need to mention the activity screen name in app_tracker.xml. If you have multiple activities, you have to mention the screen names for every activity.

Open app_tracker.xml and add below code. (Replace the package name with yours)

<screenName name="info.androidhive.googleanalytics.activity.MainActivity">Home Screen</screenName>

<screenName name="info.androidhive.googleanalytics.activity.SecondActivity">Second Screen</screenName>

⇒ Manual Screen Tracking

If you want to track the activity view manually, call the trackScreenView() in your activity onResume() method.

MyApplication.getInstance().trackScreenView("Home Screen");

android-google-analytics-tracking-activity-1

2.2 Tracking Fragment

Tacking fragment view is same as activity tracking except fragment can’t be tracking automatically. You have to manually invoke the screen view code in fragment onResume() method. We’ll test this by creating simple fragment and add it in our main activity.

14. Create an xml layout under res ⇒ layout named fragment_footer.xml.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="info.androidhive.googleanalytics.activity.FooterFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/fragment_footer"
        android:background="@color/colorAccent"
        android:padding="10dp"
        android:layout_margin="20dp"/>

</FrameLayout>

15. Create a class named FooterFragment.java and add the below code. You can notice that trackScreenView() is called in onResume() method which records the fragment view whenever the fragment is added or resumed.

MyApplication.getInstance().trackScreenView("Footer Fragment");
package info.androidhive.googleanalytics.activity;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import info.androidhive.googleanalytics.R;
import info.androidhive.googleanalytics.app.MyApplication;

public class FooterFragment extends Fragment {

    public FooterFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_footer, container, false);
    }

    @Override
    public void onResume() {
        super.onResume();

        // Tracking the screen view
        MyApplication.getInstance().trackScreenView("Footer Fragment");
    }
}

16. Now open MainActivity.java and add a click event listener to load the fragment.

/**
* Tracking Fragment View
*/
btnLoadFragment.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        FooterFragment footerFragment = new FooterFragment();
        fragmentTransaction.replace(R.id.frame_container, footerFragment);
        fragmentTransaction.commit();
    }
});

Now run the app and press the Fragment Tracking button. And after 2 – 3 mins you can the fragment screen view on Google Analytics dashboard.

android-google-analytics-tracking-fragment

2.3 Tracking Event

Event tracking allows us to record any kind of user interaction within the app. The interaction can be anything like button press, selecting a spinner, swiping gestures, completing game level etc.,

Event tracking accepts four parameters. Category, Action, Label and Value. Below is a simple event example when user presses the book download button.

MyApplication.getInstance().trackEvent("Book", "Download", "Track event example");

17. Open MainActivity.java and add below button click listener and call trackEvent() to track the event.

/**
* Event tracking
* Event(Category, Action, Label)
*/
btnSendEvent.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // Tracking Event
        MyApplication.getInstance().trackEvent("Book", "Download", "Track event example");

        Toast.makeText(getApplicationContext(), "Event \'Book\' \'Download\' \'Event example\' is sent. Check it on Google Analytics Dashboard!", Toast.LENGTH_LONG).show();
    }
});

Now run the app and press the Track Event button. On the Google Analytics dashboard click on Events to see the event sent from the app.

android-google-analytics-tracking-event

2.4 Tracking Exception

Exceptions can also be tracked very easily. This allows us to track the all the known exception which we tried to catch using try & catch block.

18. Open your MainActivity.java and add the below code. In this code we are recording a null pointer exception using try catch block. Call trackException() method to record the exception.

/**
* Tracking Exception Manually
* All known exceptions can be tracking this way
* using Try & Catch
*/
btnException.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        try {
                String name = null;
                if (name.equals("ravi")) {
                    /* Never comes here as it throws null pointer exception */
                }
            } catch (Exception e) {
                // Tracking exception
                MyApplication.getInstance().trackException(e);

                Toast.makeText(getApplicationContext(), getString(R.string.toast_track_exception), Toast.LENGTH_LONG).show();

                Log.e(TAG, "Exception: " + e.getMessage());
        }
    }
});

Now run the app and press the Track Exception button. You won’t be able to see the recorded exception right away on the dashboard. It normally takes 1 day to reflect on Google Analytics dashboard.

To see exceptions, goto Behaviour ⇒ Crashes and Exceptions on Google Analytics.

android-google-analytics-tracking-app-crash

2.5 Tracking App Crashes

App crashes happens due many unknown factors. App crash recorded automatically by setting ga_reportUncaughtExceptions to true in app_tracker.xml. We’ll test this by crashing the app intensionally.

19. Open MainActivity.java and add below code. Here we are dividing a number with zero which throws Arithmetic Exception and crashes the app.

/**
* Tracking App Crashes
* Manually generation app crash by dividing with zero
*/
btnAppCrash.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        Toast.makeText(getApplicationContext(), getString(R.string.toast_app_crash), Toast.LENGTH_LONG).show();

        Runnable r = new Runnable() {
            @Override
            public void run() {
                int answer = 12 / 0;
            }
        };

        Handler h = new Handler();
        h.postDelayed(r, 1500);
    }
});

Now run the app and press the Track App Crash. Your app should crash after 1.5 sec. This app crash will be recored and will be shown on Google Analytics dashboard. Goto Behaviour ⇒ Crashes and Exceptions section on dashboard to see the exception. This also takes 1 day to reflect on dashboard.

android-google-analytics-tracking-exception

I hope this articles gave you good start with Google Analytics SDK v4. Go through the docs and try other features offered by google analytics.

Ravi is hardcore Android programmer and Android programming has been his passion since he compiled his first hello-world program. Solving real problems of Android developers through tutorials has always been interesting part for him.