Android v4 - Getting Started

Introduction

Google Tag Manager enables developers to change configuration values in their mobile application using the Google Tag Manager interface without having to rebuild and resubmit application binaries to app marketplaces.

This is useful for managing any configuration values or flags in your application that you may need to change in the future, including:

  • Various UI settings and display strings
  • Sizes, locations, or types of ads served in your application
  • Various Game settings

Configuration values may also be evaluated at runtime using rules, enabling dynamic configurations such as:

  • Using screen size to determine ad banner size
  • Using language and location to configure UI elements

Google TagManager also enables the dynamic implementation of tracking tags and pixels in applications. Developers can push important events into a data layer and decide later which tracking tags or pixels should be fired.

Before you Begin

Complete the following steps before you begin this getting started guide:

Once you've completed these steps, the remainder of this guide will walk you through how to configure and use Google Tag Manager within your Android application.

Getting Started

After following this Getting Started guide, you'll understand how to:

This guide uses code snippets from the Cute Animals sample application included with the Google Play Services SDK. The complete source for this project is available in: <android-sdk-directory>/extras/google/google_play_services/tagmanager/cuteanimals.

1. Adding Google Tag Manager to your Project

To add Google Tag Manager to your project:

  1. Set Up the Google Play Services SDK.
  2. If you use an IDE other than Android Studio, add the following permissions to the AndroidManifest.xml file:
    <!-- For TagManager SDK -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  3. To enable InstallReferrerReceiver to call the Google Analytics receiver to set the campaign data, add the following to the AndroidManifest.xml file:
    <!-- Used for install referrer tracking-->
    <service android:name="com.google.android.gms.tagmanager.InstallReferrerService" />
    <receiver
      android:name="com.google.android.gms.tagmanager.InstallReferrerReceiver"
      android:exported="true">
      <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
      </intent-filter>
    </receiver>

2. Adding a Default Container File to your Project

Google Tag Manager uses a default container on the first run of your application. The default container will cease to be used as soon as the app is able to retrieve a fresh container over the network.

To download and add a default container binary to your application:

  1. Sign in to the Google Tag Manager web interface.
  2. Select the Version of the container you'd like to download.
  3. Click the Download button to retrieve the container binary.
  4. Add the downloaded container binary file to your project as a raw resource.
    1. If the raw subfolder under <project-root>/res/ does not exist, create it.
    2. Rename the container binary file if necessary. It consists of only lowercase letters, digits, and underscores.
    3. Copy the container binary file to the folder <project-root>/res/raw.

Although using the binary file is recommended, if your container does not contain rules or tags, you may choose to use a simple JSON file instead.

3. Initializing Google Tag Manager

To initialize Google Tag Manager in your application:

  1. Get the TagManager singleton:
    TagManager tagManager = TagManager.getInstance(this);
  2. Use the TagManager singleton to make a request to load a container, specifying a Google Tag Manager container ID as well as your default container file. The container ID should be uppercase and exactly match the container ID in the Google Tag Manager web interface. The call to loadContainerPreferNonDefault() is non-blocking and returns a PendingResult:
    PendingResult<ContainerHolder> pending =
            tagManager.loadContainerPreferNonDefault(CONTAINER_ID,
            R.raw.defaultcontainer_binary);
  3. Use a ResultCallback to return the ContainerHolder once it has finished loading or timed out:
    // The onResult method will be called as soon as one of the following happens:
    //     1. a saved container is loaded
    //     2. if there is no saved container, a network container is loaded
    //     3. the 2-second timeout occurs
    pending.setResultCallback(new ResultCallback<ContainerHolder>() {
        @Override
        public void onResult(ContainerHolder containerHolder) {
            ContainerHolderSingleton.setContainerHolder(containerHolder);
            Container container = containerHolder.getContainer();
            if (!containerHolder.getStatus().isSuccess()) {
                Log.e("CuteAnimals", "failure loading container");
                displayErrorToUser(R.string.load_error);
                return;
            }
            ContainerLoadedCallback.registerCallbacksForContainer(container);
            containerHolder.setContainerAvailableListener(new ContainerLoadedCallback());
            startMainActivity();
        }
    }, TIMEOUT_FOR_CONTAINER_OPEN_MILLISECONDS, TimeUnit.MILLISECONDS);

    Creating a ContainerHolder Singleton

    You should only maintain one instance of ContainerHolder per run of your application. That is why the above example uses a ContainerHolderSingleton utility class to manage access to the ContainerHolder instance. Here is what that ContainerHolderSingleton class looks like:

    package com.google.android.tagmanager.examples.cuteanimals;
    
    import com.google.android.gms.tagmanager.ContainerHolder;
    
    /**
     * Singleton to hold the GTM Container (since it should be only created once
     * per run of the app).
     */
    public class ContainerHolderSingleton {
        private static ContainerHolder containerHolder;
    
        /**
         * Utility class; don't instantiate.
         */
        private ContainerHolderSingleton() {
        }
    
        public static ContainerHolder getContainerHolder() {
            return containerHolder;
        }
    
        public static void setContainerHolder(ContainerHolder c) {
            containerHolder = c;
        }
    }

4. Getting Configuration Values from the Container

Once the container is loaded, you can retrieve configuration values using any of the Container.get<type>() methods. Configuration values are defined using Google Tag Manager's value collection variables. For example, the following method retrieves the latest color we've decided to use in for a UI element and returns it as an integer:

/**
 * Returns an integer representing a color.
 */
private int getColor(String key) {
    return colorFromColorName(containerHolder.getContainer().getString(key));
}

This code does two things to retrieve the color name from the container:

  1. Gets the Container from the ContainerHolder using ContainerHolder.getContainer().
  2. Gets the color value using Container.getString(key), where you have defined the key and value in the Google Tag Manager web interface.

5. Pushing Events and Values to the dataLayer

Google Tag Manager also provides a dataLayer, into which you can push information about your application that can be read in other parts of your application or used to fire tags you've configured in the Google Tag Manager web interface.

Pushing Values to the dataLayer

The dataLayer provides a layer of persistence that you can use to store key-value pairs you might want to use in other parts of your application, or as inputs to Google Tag Manager tags.

To push a value to the dataLayer, follow this pattern:

  1. Get the DataLayer singleton:
    DataLayer dataLayer = TagManager.getInstance(context).getDataLayer();
  2. Push the event using DataLayer.push():
    // Put the image_name into the data layer for future use.
    TagManager.getInstance(this).getDataLayer().push(IMAGE_NAME_KEY, imageName);

To get a value from the dataLayer, use DataLayer.get(key).

Pushing Events to the dataLayer

Pushing events to the dataLayer allows you to separate your application code from tags you might want to fire in response to those events.

For example, instead of hard-coding Google Analytics screenview tracking calls into your application, you could push screen events onto the dataLayer and define your tracking tags via the Google Tag Manager web interface. This gives you the flexibility to modify that tag, or add additional tags that respond to screen events, without updating your application code.

To push an event to the dataLayer, follow this pattern:

  1. Get the DataLayer singleton:
    DataLayer dataLayer = TagManager.getInstance(context).getDataLayer();
  2. Push the event using DataLayer.pushEvent():
    dataLayer.pushEvent("openScreen", DataLayer.mapOf("screenName", screenName));

    DataLayer.mapOf() is a utility method you can use to easily generate a map of key-value pairs that will update the dataLayer at the same time the event is pushed.

6. Previewing, Debugging, and Publishing

Before publishing a version of your container, you'll want to preview it to make sure it works as intended. Google Tag Manager gives you the ability to preview versions of your container by generating links and QR codes in the web interface and using them to open your application. You can also enable a verbose logging mode to debug any unexpected behavior.

Previewing

To preview a version of your container, follow these steps:

  1. Adding this preview Activity to your AndroidManifest file:
    <!--  Add preview activity. -->
    <activity
        android:name="com.google.android.gms.tagmanager.PreviewActivity"
        android:label="@string/app_name"
        android:noHistory="true">  <!-- optional, removes the previewActivity from the activity stack. -->
        <intent-filter>
          <data android:scheme="tagmanager.c.com.google.android.tagmanager.examples.cuteanimals" />
          <action android:name="android.intent.action.VIEW" />
          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE"/>
        </intent-filter>
    </activity>

    Be sure to modify this line to include your application's package name:

    <data android:scheme="tagmanager.c.com.google.android.tagmanager.examples.cuteanimals" />
  2. Generate a preview link in the Google Tag Manager web interface
    1. Sign in to Google Tag Manager
    2. Select the container Version to preview
    3. Click the Preview button
    4. Enter your application's package name and click Generate begin preview link
  3. Use the generated link or QR Code to launch your application
  4. You can exit preview mode by following a link generated by the Generate end preview link option in the web interface.

Debugging

If you need to troubleshoot your container implementation, enable verbose logging by calling TagManager.setVerboseLoggingEnabled(true):

// Modify the log level of the logger to print out not only
// warning and error messages, but also verbose, debug, info messages.
tagManager.setVerboseLoggingEnabled(true);

Publishing

After you've previewed your container and verified it's working as intended, you can publish your container. Your container configuration values, tags, and events will be live for users the next time their containers are refreshed. Learn more about refreshing containers.

Advanced Configuration

The following sections describe advanced configuration options you want to use to further customize your Google Tag Manager implementation.

Refreshing the Container

By default, your container becomes eligible to be refreshed every 12 hours. To manually refresh the container, use ContainerHolder.refresh():

ContainerHolderSingleton.getContainerHolder().refresh();

This is an asynchronous call that will not return immediately. To reduce network traffic, refresh() may only be called once every 15 minutes, otherwise it will be a no-op.