Treasure Data Android SDK

This article get you started sending data from your Android app to Treasure Data, using our Android SDK library. Using these steps, you don’t need to install anything server-side to track your mobile application’s activities.

Table of Contents

Prerequisites

  • Basic knowledge of Android Development
  • Android 2.3 , or later
  • Basic knowledge of Treasure Data.

How to install Android SDK?

This video demonstrates how to install Android SDK in 5 minutes.

Step 1: Install the Library

Gradle

If you use gradle, add the following dependency to dependencies directive in the build.gradle.

dependencies {
  compile 'com.treasuredata:td-android-sdk:0.1.13'
}

Maven

If you use maven, add the following directives to your pom.xml under <dependencies>. pom.xml in an example Android application project could be a good reference.

<dependency>
  <groupId>com.treasuredata</groupId>
  <artifactId>td-android-sdk</artifactId>
  <version>0.1.13</version>
</dependency>

Jar File

If you don’t use Maven, please put td-android-sdk-x.x.x-shaded.jar (get the latest here) into (YOUR_ANDROID_PROJECT)/libs.

Step 2: Enable Required Android Permissions

If it’s not already present, add the INTERNET permission to your AndroidManifest.xml file. The entry below should appear between the <manifest> .. </manifest> tags. The example is here.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.treasuredata.android.demo"
  android:versionCode="1"
  android:versionName="1.0" >
  ...

  <!-- required permission -->
  <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

Step 3: Initialize the Library at onCreate()

Please create the TreasureData object at the onCreate() method of your main activity. Here’s an example code:

public class ExampleActivity extends Activity {
  private TreasureData td;

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

    // Initialize Treasure Data Android SDK
    // @see https://docs.treasuredata.com/articles/android-sdk
    TreasureData.initializeApiEndpoint("https://in.treasuredata.com");
    TreasureData.initializeEncryptionKey("RANDOM_STRING_TO_ENCRYPT_DATA");
    TreasureData.disableLogging();
    td = TreasureData.initializeSharedInstance(this, "YOUR_WRITE_ONLY_API_KEY");
    td.setDefaultDatabase("your_application_name");
    td.enableAutoAppendUniqId();
    td.enableAutoAppendModelInformation();
    td.enableAutoAppendAppInformation();
    td.enableAutoAppendLocaleInformation();
  }
}

You can get the API key from the (Treasure Data Console). It’s recommended to use a write-only API key for SDKs.

Step 4: Buffer the events locally

Next, call the addEvent(String table, Map<String, Object> record) function at the appropriate timing within your applications. This example sends an event to the button_clicks table, when the button is clicked.

Untitled-3
We generally recommend to use application's name as a database name, and event name as a table name.
View v = findViewById(R.id.button);
v.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    final Map event = new HashMap<String, Object>();
    event.put("name", "foo bar");
    event.put("age", 42);
    event.put("comment", "hello world");
    td.addEvent("button_clicks", event);
  }
});

With this call, the record like below will be immediately bufferred on the disk.

{
  "td_uuid":"c123470de-3950-4997-b321-07d6f5b4a3",
  "td_os_type":"Android",
  "td_os_ver":"15",
  "td_device":"ISW11SC",
  "td_model":"ISW11SC",
  "td_display":"IMM76D.KDLPL",
  "td_brand":"KDDI",
  "td_board":"ISW11SC",
  "td_app_ver":"1.9.2",
  "td_app_ver_num":"11",
  "td_locale_country":"US",
  "td_locale_lang":"en",
  "name":"foo bar",
  "age":42,
  "comment":"helloworld"
}

By default, all events will be bufferred on the disk. You need to explicitly flush the bufferred data to the cloud. It won’t be uploaded automatically. Next section will describe how to flush the buffer.

Step 5: Session Tracking and Events Upload at onStart() / onStop()

Finally, please call TreasureData.startSession() and TreasureData.endSession() at onStart() and onStop(). Then, please call uploadEvents() at onStop() too. As we described, uploadEvents() function will flush the buffer and send the data to the cloud. In case upload fails, it will automatically retry in a background thread.

protected void onStart(Bundle savedInstanceState) {
  TreasureData.startSession(this);
  td.addEvent("on_start_calls", ...); // optional but recommended
  Log.i(TAG, "onStart(): Session ID=" + TreasureData.getSessionId(this)); // You can get the current session ID like this
}

protected void onStop() {
  TreasureData.endSession(this);
  td.addEvent("on_stop_calls", ...); // optional but recommended
  td.uploadEvents();
}

As long as there is any Context that has called startSession() but not endSession(), the session will be continued. Also, if a new Context calls startSession() within 10 seconds of the last Context calling endSession(), then the session will be resumed, instead of a new session being created.

Untitled-3
IP whitelist won't be applied to any import from Android SDK. Also we've seen a lot of cases where a lot of Android devices have an invalid timestamp (like 1970/01/01), so we're currently ignoring the log which has a timestamp older than 7 days, and newer than 3 days ahead.

Step 6: Track the App Installation

You can collect the first run event of your application, which can be used to track app installation event. isFirstRun() and clearFirstRun() methods would be useful.

@Override
protected void onCreate(Bundle savedInstanceState) {
  ...
  if (td.isFirstRun(this)) {
    Map<String, Object> event = new HashMap<String, Object>();
    event.put("first_run", true);
        :

    td.addEventWithCallback("events", event, new TDCallback() {
      @Override
      public void onSuccess() {
        td.clearFirstRun(MainActivity.this);
        td.uploadEvents();
      }
      @Override
      public void onError(String errorCode, Exception e) {
        Log.w(TAG, "TreasureData.addEvent:onError errorCode=" + errorCode + ", ex=" + e);
      }
    });
  }
}

Parameters Captured

Here is a list of parameters captured by the Android SDK:

- td_session_id
- td_uuid : unique ID for the combination of application and device
- td_board : android.os.Build#BOARD
- td_brand : android.os.Build#BRAND
- td_device : android.os.Build#DEVICE
- td_display : android.os.Build#DISPLAY
- td_model : android.os.Build#MODEL
- td_os_ver : android.os.Build.VERSION#SDK_INT
- td_os_type : "Android"
- td_app_ver : android.content.pm.PackageInfo.versionName (from Context.getPackageManager().getPackageInfo())
- td_app_ver_num : android.content.pm.PackageInfo.versionCode (from Context.getPackageManager().getPackageInfo())
- td_locale_country : java.util.Locale.getCountry() (from Context.getResources().getConfiguration().locale)
- td_locale_lang : java.util.Locale.getLanguage() (from Context.getResources().getConfiguration().locale)

Advanced Tips

Access shared TreasureData instance

You can use a shared instance from anywhere with TreasureData.sharedInstance() method after calling TreasureData.initializeSharedInstance().

public class MainActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    TreasureData.initializeSharedInstance(this, "YOUR_WRITE_ONLY_API_KEY");
    TreasureData.sharedInstance().setDefaultDatabase("application_name");
  }
}

public class OtherActivity extends Activity {
  public void onDataLoadSomethingFinished(long elapsedTime) {
    Map<String, Object> event = new HashMap<String, Object>();
    event.put("data_type", "something");
    event.put("elapsed_time", elapsedTime);
    TreasureData.sharedInstance().addEvent("events", event);
  }
}

Sending data with Array type

Android SDK can handle java.util.List or java.lang.String[] to send data with Array type. But, it doesn’t handle JSONArray since internal library jackson.databind doesn’t deal with JSONArray.

event.put("array", Arrays.asList("one", "two", "three"));

Next Steps

For transparency, we’re open sourcing our iOS SDK on Github. Please check the repository if necessary.


Last modified: Jun 27 2016 04:15:00 UTC

If this article is incorrect or outdated, or omits critical information, please let us know. For all other issues, please see our support channels.