Analytics for Android

Community x
Maintenance ✓
Flagship x
?

Maintenance libraries send data as intended but receive no new feature support and only critical maintenance updates from Segment. When possible, Segment recommends using a Flagship version of these libraries.


Current Version: 4.11.3

Release Date: May 17, 2023

Analytics for Android makes it easier for you to send data to any tool without having to learn, test or implement a new API every time.

Analytics for Android only supports any Android device running API 14 (Android 4.0) and higher. This includes Amazon Fire devices.

Analytics-Kotlin

The Analytics-Kotlin library is in General Availability. You can use Analytics-Kotlin for mobile or server applications. If you’d like to upgrade to Analytics-Kotlin, see the migration guide. Segment’s future development efforts concentrate on the new Analytics-Kotlin SDK, and will only ship security updates for the Analytics-Android SDK.

In addition to the documentation here, you can also read the Javadocs for all versions of Analytics-Android on Javadoc.io.

Analytics-Android and Unique Identifiers

One of the most important parts of any analytics platform is the ability to consistently and accurately identify users. To do this, the platform must assign and persist some form of identification on the device, so you can analyze user actions effectively. This is especially important for funnel conversion analysis and retention analysis.

Naturally the Analytics SDK needs a unique ID for each user. The very first time an Android app that uses Segment launches, the Segment SDK generates a UUID and saves it on the device’s disk. This is used as the anonymousId and stays constant for the user on the device. To create a new user on the same device, call reset on the Analytics client.

The Segment SDK also collects the Advertising ID provided by Play Services. Make sure the Play Services Ads library is included as a dependency for your application. This is the ID that should be used for advertising purposes. This value is set to context.device.advertisingId.

Segment also generates a unique ID by using the DRM API as context.device.id. Some destinations rely on this field being the Android ID, so be sure to double-check the destination’s vendor documentation. If you choose to override the default value, make sure the identifier you choose complies with Google’s User Data Policy. Note: If this ID didn’t generate previously (for example, because the app was newly installed or updated from an older version), an empty string shows before the ID generation completes.

Note: From 4.10.1, Segment no longer collects the Android ID to comply with Google’s User Data Policy. You may need to upgrade your Analytics-Android version and your device-mode destination versions to be compliant with Google Play policies.

API call queuing in Analytics-Android

The Analytics-Android library queues API calls and uploads them in batches. This limits the number of network calls made, and helps save battery on the user’s device.

When you send an event, the library saves it to disk. When the queue size reaches the maximum size you specify (20 by default), the library flushes the queue and uploads the events in a single batch. Since the data is saved immediately, it isn’t lost even if the app is killed or the operating system crashes.

The queue behavior might differ for Device-mode destinations. For example, Mixpanel’s SDK queues events and then flushes them only when the app goes to the background.

This is why even if you see events in the debugger, the Device-mode destination may not show them on their dashboards yet because they might still be in their mobile SDK’s queue. The opposite may also happen: the Device-mode destination SDK might send events to its servers before Segment sends its queue, so events could show up in the destination’s dashboard before they appear in the Segment debugger.

Queue persistence in Analytics-Android

Analytics-Android uses a persistent disk queue, so the events persist even when the app is killed. On app restart, the library reads them from disk and uploads the events. The queue works on top of Tape, which is designed to even survive process and system crashes.

Analytics-Android saves up to 1000 calls on disk, and these never expire.

Getting Started

About mobile connection modes

Segment defaults to using cloud-based connection mode (“cloud-mode”) for any destination connected to a mobile source, because this can help decrease the size of your final app package. When you use cloud-mode, Segment sends messages to the Segment servers, and then translates and forwards that data on to the downstream tools. This way, you only package the Segment mobile library with your app.

However, many destination tools that specifically deal with mobile interactions require that you use a device-based connection mode (“device-mode”) so that they can collect information directly on the mobile device. (You can check the full list of destinations and which connection modes they support.)

If you plan to use destinations that require device-mode, you must package the Segment-integration version of that tool’s SDK along with the Segment source library in your app. The Segment-integration SDK allows you to still collect the data with Segment, but also enables any device-based features, and still saves you space.

When you package a tool’s device-mode SDK with the Segment SDK, Segment sends the data directly to the tool’s API endpoint. Segment then also adds the tool to the integrations object and sets it to false, so that the data is not sent a second time from Segment servers.

For example, if you bundled the Segment SDK and Segment-Intercom library, you would see this in your payload:

"integrations": {
  "Intercom": false
  },

When you package Segment and the Segment-integration SDKs, you must use a dependency manager (such as Cocoapods or Gradle) to ensure that all SDKs are compatible and all of their dependencies are included. Segment does not support bundling mobile SDKs without a dependency manager.

Create an Android source

Before you start installing the Analytics-Android library, create an Android Source in Segment. This tells the Segment servers that you’ll be sending them data from this type of source.

  1. Go to the Segment App, and sign in to the Workspace you want to send your Android data to.
  2. Click Sources, then Add Source
  3. Select an Android source from the catalog and click Add Source.
  4. Give the new source a name, and optionally any labels that might apply. Click Add Source to save the changes.

Once you save the source, go to the Settings tab and click API Keys in the left navigation. Find and write down your Write Key, as you’ll need it later to set up your environment. The Write Key is how Segment knows that data coming from your app is really coming from you!

Step 1: Install the Library

The easiest way to install the Analytics-Android library is using a build system like Gradle. This makes it simple to upgrade versions and add destinations. The library is distributed using Maven Central. Just add the analytics module to your build.gradle file as in the example lines below:

dependencies {
  implementation 'com.segment.analytics.android:analytics:4.+'
  }

Packaging SDKs for Device-mode destinations

To keep the Analytics-Android SDK lightweight, the analytics artifact only installs the Segment destination. This means that all your data is sent using Segment’s servers to any tools you’ve enabled with cloud-mode-compatible destinations.

As described here, some destinations require or offer Device-mode SDKs. for these destinations, you must package the destination SDK, which might require some additional steps.

Now that the SDK is installed and set up, you’re ready to…

Step 2. Initialize the Client

We recommend initializing the client in your Application subclass. You’ll need your Segment Write Key for your Android Source.

// Create an analytics client with the given context and Segment write key.
Analytics analytics = new Analytics.Builder(context, YOUR_WRITE_KEY)
  .trackApplicationLifecycleEvents() // Enable this to record certain application events automatically!
  .recordScreenViews() // Enable this to record screen views automatically!
  .build();

// Set the initialized instance as a globally accessible instance.
Analytics.setSingletonInstance(analytics);
// Create an analytics client with the given context and Segment write key.
val analytics = Analytics.Builder(context, YOUR_WRITE_KEY)
  .trackApplicationLifecycleEvents() // Enable this to record certain application events automatically!
  .recordScreenViews() // Enable this to record screen views automatically!
  .build()

// Set the initialized instance as a globally accessible instance.
Analytics.setSingletonInstance(analytics);

Notes:

  • You can automatically track lifecycle events such as Application Opened, Application Installed, Application Updated to start quickly with core events. These are optional, but highly recommended.
  • This only installs the Segment destination. This means that all your data is sent server-side to tools. To bundle additional destinations client-side, you’ll need to take some additional steps as shown here.

Customize the Client (Optional)

The entry point of the library is through the Analytics class. As you might have seen in the quickstart, here’s how you initialize the Analytics client with it’s defaults.

Analytics analytics = new Analytics.Builder(context, writeKey).build();
val analytics = Analytics.Builder(context, writeKey).build()

The Analytics.Builder class lets you customize settings for the Analytics client, including things like the flush interval and packaging Device-mode destinations. Refer to the Javadocs for details on customizable parameters.

We also maintain a global default instance which is initialized with defaults suitable to most implementations.

// You can also register your custom instance as a global singleton.
Analytics.setSingletonInstance(analytics);
Analytics.with(context).track(...);
// You can also register your custom instance as a global singleton.
Analytics.setSingletonInstance(analytics)
Analytics.with(context).track(...)

In general, Segment recommends that you use the Builder method because it provides the most flexibility. Remember you can call Analytics.setSingletonInstance only ONCE, so it’s best to put the initialization code inside your custom Application class.

public class MyApp extends Application {
  @Override public void onCreate() {
    Analytics analytics = new Analytics.Builder(context, writeKey).build();
    Analytics.setSingletonInstance(analytics);

    // Safely call Analytics.with(context) from anywhere within your app!
    Analytics.with(context).track("Application Started");
  }
}
class MyApp : Application() {
  override fun onCreate() {
    val analytics = Analytics.Builder(context, writeKey).build()
    Analytics.setSingletonInstance(analytics)

    // Safely call Analytics.with(context) from anywhere within your app!
    Analytics.with(context).track("Application Started")
  }
}

Once you initialize an Analytics client, you can safely call any of its tracking methods from any thread. These events are dispatched asynchronously to the Segment servers and to any Device-mode destinations.

Note: You should only ever initialize ONE instance of the Analytics client. These are expensive to create and throw away, and in most cases, you should stick to Segment’s singleton implementation to make using the SDK easier.

Step 3. Add Permissions

Ensure that the necessary permissions are declared in your application’s AndroidManifest.xml.

 <!-- Required for internet. -->
<uses-permission android:name="android.permission.INTERNET"/>

Data Collection - The Basic Segment API calls

The Segment API calls include:

Identify

Good to know: For any of the different methods described in this doc, you can replace the properties and traits in the code samples with variables that represent the data collected.

Identify calls let you tie a user to their actions, and record traits about them. It includes a unique User ID and any optional traits you know about them.

Example identify call:

Analytics.with(context).identify("a user's id", new Traits().putName("John Doe"), null);
Analytics.with(context).identify("a user's id", Traits().putName("John Doe"), null)

The example call below sets the anonymousId to a custom value of test_anonymousId.

Analytics.with(context).identify(new Traits().putValue("anonymousId","test_anonymousId"));
Analytics.with(context).identify(Traits().putValue("anonymousId","test_anonymousId"))

Segment recommends that you make an Identify call once when the user’s first creates an account, and only using the Identify call later when their traits change. Segment remembers the previous userIDs and merges the new traits with the old ones.

// Initially when you only know the user's name
Analytics.with(context).identify(new Traits().putName("Michael Bolton"));

// Sometime later in your app when the user gives you their email
Analytics.with(context).identify(new Traits().putEmail("mbolton@example.com"));
// Initially when you only know the user's name
Analytics.with(context).identify(Traits().putName("Michael Bolton"))

// Sometime later in your app when the user gives you their email
Analytics.with(context).identify(Traits().putEmail("mbolton@example.com"))

Remember, you can replace the properties and traits in the code samples with variables that represent the data you actually collected.

The Identify call has the following fields:

userId String,optional The database ID for this user.
traits Traits,optional A map of traits about the user, such as their name, email, address, etc.
options Options, optional Extra options for the call.

The Android library currently automatically sends the userId and anonymousId as traits. Additionally, traits are sent in the context.traits field with every message.

Track

The Track call lets you record the actions your users perform. Every action triggers what we call an “event”, which can also have associated properties.

To get started, the Analytics-Android SDK can automatically tracks a few key common events using the Segment Native Mobile Spec, such as the Application Installed, Application Updated and Application Opened. You can enable this option during initialization.

You might also want to track events that indicate success for your mobile app, like Signed Up, Item Purchased or Article Bookmarked. Segment recommends tracking just a few important events. You can always add more later!

Example track call:

Analytics analytics = new Analytics.Builder(context, writeKey)
  .trackApplicationLifecycleEvents()
  .build();

Analytics.with(context).track("Product Viewed", new Properties().putValue("name", "Moto 360"));

val analytics = Analytics.Builder(context, writeKey)
  .trackApplicationLifecycleEvents()
  .build()

Analytics.with(context).track("Product Viewed", Properties().putValue("name", "Moto 360"))

This example Track call tells us that your user just triggered the Product Viewed event with a name of “Moto 360.”

The Track call properties can be anything you want to record, for example:

Analytics.with(context).track("Purchased Item", new Properties().putValue("sku", "13d31").putRevenue(199.99));
Analytics.with(context).track("Purchased Item", Properties().putValue("sku", "13d31").putRevenue(199.99))

The Track call includes the following fields:

name String,required A name for the tracked action.
properties Properties,optional A map of properties for this action, e.g. revenue if the action was a purchase.
options Options,optional Extra options for the call.

Screen

The Screen method lets you you record whenever a user sees a screen of your mobile app, along with optional extra information about the page being viewed.

You’ll want to record a screen event an event whenever the user opens a screen in your app. This could be a view, fragment, dialog or activity depending on your app.

Not all services support screen, so when it’s not supported explicitly, the screen method tracks as an event with the same parameters.

Example screen call:

// category "Feed" and a property "Feed Length"
Analytics.with(context).screen("Feed", new Properties().putValue("Feed Length", "26"));

// no category, name "Photo Feed" and a property "Feed Length"
Analytics.with(context).screen(null, "Photo Feed", new Properties().putValue("Feed Length", "26"));

// category "Smartwatches", name "Purchase Screen", and a property "sku"
Analytics.with(context).screen("Smartwatches", "Purchase Screen", new Properties().putValue("sku", "13d31"));
// category "Feed" and a property "Feed Length"
Analytics.with(context).screen("Feed", Properties().putValue("Feed Length", "26"))

// no category, name "Photo Feed" and a property "Feed Length"
Analytics.with(context).screen(null, "Photo Feed", Properties().putValue("Feed Length", "26"))

// category "Smartwatches", name "Purchase Screen", and a property "sku"
Analytics.with(context).screen("Smartwatches", "Purchase Screen", Properties().putValue("sku", "13d31"))

The screen call has the following fields:

category String,optional* A category for the screen. Optional if name is provided.
name String,optional* A name for the screen. Optional if category is provided.
properties Properties,optional A map of properties for this screen.
options Options,optional Extra options for the call.

Find details on the Screen payload in the Segment Screen call spec.

Automatic Screen Tracking

The Segment SDK can automatically instrument screen calls, using the label of the activity you declared in the manifest as the screen’s name. Fragments and views do not trigger screen calls automatically, however you can manually call the Screen method for these.

Analytics analytics = new Analytics.Builder(context, writeKey)
  .recordScreenViews()
  .build();
val analytics = Analytics.Builder(context, writeKey)
  .recordScreenViews()
  .build()

Group

Group calls let you associate an identified user user with a group. A group could be a company, organization, account, project or team! It also lets you record custom traits about the group, like industry or number of employees.

This is useful for tools like Intercom, Preact and Totango, as it ties the user to a group of other users.

Example group call:

Analytics.with(context).group("a user's id", "a group id", new Traits().putEmployees(20));
Analytics.with(context).group("a user's id", "a group id", Traits().putEmployees(20))

The group call has the following fields:

userId String,required The database ID for this user.
groupdId String,required The database ID for this group.
traits Traits,optional A map of traits about the group, such as the number of employees, industry, etc.
options Options,optional Extra options for the call.

Find more details about the Group method, including the Group call payload, in the Segment Group call spec.

Alias

Alias is how you associate one identity with another. This is an advanced method, but it is required to manage user identities successfully in some Segment destinations, such as Mixpanel or Kissmetrics.

Mixpanel used the Alias call to associate an anonymous user with an identified user once they sign up. For Kissmetrics, if your user switches IDs, you can use ‘alias’ to rename the ‘userId’.

Example alias call:

Analytics.with(context).alias(newId);
Analytics.with(context).identify(newId);
Analytics.with(context).alias(newId)
Analytics.with(context).identify(newId)

The alias call has the following fields:

newId String,required The new ID to track this user with.
options Options,optional Extra options for the call.

For more details about alias, including the alias call payload, check out the Segment Alias call spec.

Note that the previousId is the value passed in as the userId, which Segment cached after you made an identify call. Segment passes that value as the previousId when you call alias and pass in a newId. If you have not called identify, the previousId is set to the anonymousId.

Context

Context is a dictionary of extra information you can provide about a specific API call. You can add any custom data to the context dictionary that you want to have access to in the raw logs. Some keys in the context dictionary have semantic meaning and are collected for you automatically, such as information about the user’s device.

AnalyticsContext analyticsContext = Analytics.with(context).getAnalyticsContext();
analyticsContext.putValue(...).putReferrer(...).putCampaign(...);
val analyticsContext = Analytics.with(context).analyticsContext
analyticsContext.putValue(...).putReferrer(...).putCampaign(...)

You can read more about these special fields in the Segment Common spec documentation.

To alter data specific to the device object you can use the following:

AnalyticsContext analyticsContext = Analytics.with(context).getAnalyticsContext();
analyticsContext.device().putValue("advertisingId", "1");
val analyticsContext = Analytics.with(context).analyticsContext
analyticsContext.device().putValue("advertisingId", "1")

To opt out of automatic data collection, clear the context after initializing the client. Do this BEFORE you send any events.

Analytics analytics = new Analytics.Builder(context, writeKey).defaultOptions(defaultOptions).build();
AnalyticsContext context = getAnalyticsContext();
context.clear();
val analytics = Analytics.Builder(context, writeKey).defaultOptions(defaultOptions).build()
val context = analytics.analyticsContext
context.clear()

Routing collected data

Once you set up calls using the basic Segment data collection APIs, choose which destinations to send it to, and how you want to send it to them.

Sending Data to destinations

There are two ways to send data to your analytics services through this library:

  1. Through the Segment servers, also known as “cloud-mode”
  2. Directly from the user’s device (also known as “device-mode”) using bundled SDKs

Note: Refer to the specific destination’s docs to see if your tool must be bundled in the app or sent server-side.

Cloud-Mode in Android

When a destination is enabled for your Android source from the Segment web app, but you haven’t packaged its SDK with your app, requests go through the Segment REST API, and are routed to the destination service’s API as described here. Most, but not all destinations offer a cloud-based connection mode, so it’s a good idea to check for destinations that you might need to package.

Packaging device-mode destination SDKs

By default, Segment’s analytics artifact does not package Device-mode destination SDKs.

We recommend using device-mode destinations on a need-to-use basis only, to reduce the size of your application, and to avoid running into the dreaded 65k method limit.

To package Device-mode destinations, first add the dependencies you need to your project. You can find these in the Segment app when you open the destination for your source.

compile('com.segment.analytics.android.integrations:google-analytics:+') {
  transitive = true
}
compile('io.branch.segment.analytics.android.integrations:library:+') {
  transitive = true
}

Once you add the dependency, register the destination with the Analytics-Android SDK.

Analytics analytics = new Analytics.Builder(context, writeKey)
  .use(GoogleAnalyticsIntegration.FACTORY)
  .use(BranchIntegration.FACTORY)
  ...
  .build();
val analytics = Analytics.Builder(context, writeKey)
  .use(GoogleAnalyticsIntegration.FACTORY)
  .use(BranchIntegration.FACTORY)
  ...
  .build()

Selecting Destinations

You can pass an options object on any of the basic Segment API calls that allows you to turn specific destinations on or off. By default, all destinations are enabled. (In Segment’s other libraries, you could do this in the list of integrations inside the options object.)

In the examples below, the first event is sent to all destinations, but the second one is sent to all except Mixpanel.

// Sent to all destinations
Analytics.with(context).track("Viewed Item", new Properties());

// Sent to all destinations, except Mixpanel
Analytics.with(context).track("Purchased Item", new Properties(), new Options().setIntegration("Mixpanel", false));

// Sent only to Google Analytics and Countly
Analytics.with(context).track("Purchased Item", new Properties(), new Options().setIntegration(Options.ALL_INTEGRATIONS_KEY, false).setIntegration("Countly", true).setIntegration("Google Analytics", true));
// Sent to all destinations
Analytics.with(context).track("Viewed Item", Properties())

// Sent to all destinations, except Mixpanel
Analytics.with(context).track("Purchased Item", Properties(), Options().setIntegration("Mixpanel", false))

// Sent only to Google Analytics and Countly
Analytics.with(context).track("Purchased Item", Properties(), Options().setIntegration(Options.ALL_INTEGRATIONS_KEY, false).setIntegration("Countly", true).setIntegration("Google Analytics", true))

If you build your own instance of the client, you can also specify a default options object to use for each call. In the example below, NONE of the analytics events are sent to Heap.

// Disable Heap destination
Options defaultOptions = new Options().setIntegration("Heap", false);

// Attach the options to our client
Analytics analytics = new Analytics.Builder(context, writeKey).defaultOptions(defaultOptions).build();
// Set the client as a global singleton so it can be called from anywhere
Analytics.setSingletonInstance(analytics);

// Now any calls made with this Analytics client won't be sent to Heap
Analytics.with(context).track("Viewed Item", new Properties());
// Disable Heap destination
val defaultOptions = Options().setIntegration("Heap", false)

// Attach the options to our client
val analytics = Analytics.Builder(context, writeKey).defaultOptions(defaultOptions).build()
// Set the client as a global singleton so it can be called from anywhere
Analytics.setSingletonInstance(analytics)

// Now any calls made with this Analytics client won't be sent to Heap
Analytics.with(context).track("Viewed Item", Properties())

Notice that the first example uses an Enum to disable the destination, but the second example uses a String. Segment recommends that you use the Enum method for Device-mode destinations, and use the String method to change the behavior of Cloud-mode destinations. The Enum method ensures type safety, and prevents you from accidentally disabling “GoogleAnalytics” instead of “Google Analytics”, while the String method gives you more flexibility in what options you pass to cloud-mode destinations.

Destination name flags are case sensitive and match the destination’s name in the docs In some cases where a destination’s name has more than one spelling (for example if it changed names, or brand capitalization styles, or if it was commonly misspelled and we added an alias) the documentation for that destination will include a section called “Adding (destination name) to the integrations object”.

Note: If you are on a business tier Segment plan, you can filter track calls right from the Segment App in the source schema page. This is a much simpler way to manage your filters, and you can update it without having to make and publish code changes.

Utility methods

Retrieve AnonymousId

You can retrieve the anonymousId set by the library by using:

Analytics.with(context).getAnalyticsContext().traits().anonymousId();
Analytics.with(context).analyticsContext().traits().anonymousId()

Reset

The reset method clears the SDK’s internal stores for the current user and group. This is useful for apps where users log in and out with different identities on the same device over time.

The example code below clears all information about the user.

Analytics.with(context).reset();
Analytics.with(context).reset()

Reset does not clear events in the queue, and any remaining events in the queue are sent the next time the app starts. You might want to call Flush before you call Reset.

Note: When you call reset, the next time the app opens Segment generates a new AnonymousId. This can impact the number of Monthly Tracked Users (MTUs) you process.

Collecting Stats

Local device stats help you quickly see how many events you sent to Segment, the average time bundled destinations took to run, and similar metrics.

StatsSnapshot snapshot = Analytics.with(context).getSnapshot();
log(snapshot.integrationOperationAverageDuration);
log(snapshot.flushCount);
val snapshot = Analytics.with(context).snapshot()
log(snapshot.integrationOperationAverageDuration)
log(snapshot.flushCount)

Adding debug logging

If you run into issues while using the Android library, you can enable logging to help trace the issue. Logging also helps you see how long destinations take to complete their calls so you can find performance bottlenecks.

The logging is enabled by default in the default singleton instance if your application is running in debug mode. If you use a custom instance, attach a LogLevel to the Builder and set the logging level there, as in the example below.

Analytics analytics = new Analytics.Builder(context, writeKey).logLevel(LogLevel.VERBOSE)...build();
val analytics = Analytics.Builder(context, writeKey).logLevel(LogLevel.VERBOSE)...build()

You can choose to disable logging completely (LogLevel.NONE), enable basic logging for the SDK (LogLevel.BASIC), enable basic logging for Device-mode destination (LogLevel.INFO), or simply log everything (LogLevel.VERBOSE).

Segment recommends that you turn logging off in production modes of your app.

Privacy methods

Opt-out

Depending on the audience for your app (for example, children) or the countries where you sell your app (for example, the EU), you may need to offer the ability for users to opt-out of analytics data collection inside your app. You can turn off ALL destinations including Segment itself:

Analytics.with(this).optOut(true);
Analytics.with(this).optOut(true)

Set the opt-out status for the current device and analytics client combination. This flag persists across device reboots, so you can call it once in your application, such as in a screen where a user can opt out of analytics tracking.

Anonymizing IP

The Segment iOS, Android, Analytics.js and Xamarin libraries automatically derive and set the IP address for events recorded on the user’s device. The IP is not collected on the device itself, but instead is filled in by Segment’s servers when they receive a message.

To prevent Segment from recording the users’ IP in destinations and S3, you can set the event’s context.ip field to 0.0.0.0. The Segment servers won’t overwrite this data if it comes from the client, and so do not record the IP address of the client.

Formatting Order Completed Events

Segment’s Android library provides several helper methods so you can easily construct both properties objects and products lists so your Order Completed events conform to the Segment ecommerce specification. Here’s a code example:

import com.segment.analytics.Analytics;
import com.segment.analytics.Properties;
import com.segment.analytics.Properties.Product;

// initialize a new properties object
Properties properties = new Properties();

// add orderId and revenue to the properties object
properties.putValue("orderId", String orderId).putValue("revenue", double revenue);

// initialize a new product
Product product1 = new Product(String id, String sku, double price);

// initialize a second product
Product product2 = new Product(String id, String sku, double price);

// add products to the properties object
properties.putProducts(product1, product2);

// pass the properties object into your Order Completed event
Analytics.with(context).track("Order Completed", properties);
import com.segment.analytics.Analytics
import com.segment.analytics.Properties
import com.segment.analytics.Properties.Product

// initialize a new properties object
val properties = Properties();

// add orderId and revenue to the properties object
properties.putValue("orderId", orderId).putValue("revenue", revenue)

// initialize a new product
Product product1 = Product(id, sku, price)

// initialize a second product
Product product2 = Product(id, sku, price)

// add products to the properties object
properties.putProducts(product1, product2)

// pass the properties object into your Order Completed event
Analytics.with(context).track("Order Completed", properties)

Find details on best practices in event naming as well as the Track method payload in the Segment Track call spec.

Proxying HTTP Calls

You can point the Android SDK to your own hosted proxy of the Segment API. This runs the HTTP traffic for the Segment API through the proxy.

Analytics analytics = new Analytics.Builder(this, ANALYTICS_WRITE_KEY) //
        .connectionFactory(new ConnectionFactory() {
          @Override protected HttpURLConnection openConnection(String url) throws IOException {
            String path = Uri.parse(url).getPath();
            // Replace YOUR_PROXY_HOST with the address of your proxy
            return super.openConnection("YOUR_PROXY_HOST" + path);
          }
        })
        .build();
val analytics = Analytics.Builder(this, ANALYTICS_WRITE_KEY) //
        .connectionFactory(object: ConnectionFactory() {
          @Throws(IOException::class)
          override fun openConnection(url: String): HttpURLConnection {
            val path = Uri.parse(url).path
            // Replace YOUR_PROXY_HOST with the address of your proxy
            return super.openConnection("YOUR_PROXY_HOST$path")
          }
        })
        .build()

Analytics-Android Versions

This section includes information on:

Bleeding Edge Releases

Segment publishes stable releases every second Wednesday, when we tag and release the master branch.

After releasing, we also merge the dev branch merged into master. In general, code will be available on master for two weeks before being tagged as a stable release. During this period, master is published as a snapshot — the equivalent of bleeding edge releases. We recommend using the snapshot version to try out upcoming features and fixes that have not been published yet. Simply add the snapshots repo to your repository and Gradle will pull in the latest snapshot build.

repositories {
  mavenCentral()
  maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

Support for Older versions of Android

The Analytics-Android library supports back to API level 14 (Android 4.0). You should consider it too! If you can’t do this for your own application, there are three options we recommend:

  1. Use an older version of the Analytics-Android library that supports your minimum requirements. Remember that there won’t be any updates or bug fixes to those versions, but you might still have clients using old versions of the library in production.
  2. Skip running analytics for users on older devices by wrapping calls to the Analytics-Android SDK in a Build.VERSION check.
  3. Write your own SDK. You can still use most of the tools on Segment using the HTTP API. You can use either the Analytics-Android or Java source to get a quick head start.

Migrating from v2 to v3

Version 3 deprecated in favor of Version 4

See the section below for instructions on how to upgrade.

If you are already using version 2 of the Android SDK, you’ll have to make few changes to get up and running with version 3.

In version 3, we’ve organized the destinations to be make the core SDK even leaner and smaller. This is what the old set up looked like:

compile('com.segment.analytics.android:analytics-core:+') {
  transitive = true
}

// Add other dependencies as you want here
compile 'com.google.android.gms:play-services:+'
compile 'com.mixpanel.android:mixpanel-android:+@aar'
compile files('libs/QuantcastAndroidSdk.jar')

In the new version, instead of adding the destinations directly, simply add the Segment destination modules as a dependency instead. This also ensures that the version of the Device-mode destination you’re using matches the one we depend on.

compile('com.segment.analytics.android:analytics-core:+') {
  transitive = true
}

// Add other dependencies as you want here
compile('com.segment.analytics.android:analytics-integration-google-analytics:+') {
  transitive = true
}
compile('com.segment.analytics.android:analytics-integration-mixpanel:+') {
  transitive = true
}
compile('com.segment.analytics.android:analytics-integration-quantcast:+') {
  transitive = true
}

Earlier, you could control the debugging behaviour with a boolean flag. In version 3, this is replaced by the more powerful LogLevel Enum, that lets you not only control the logging behavior of the Analytics-Android SDK, but also for Device-mode destinations.

Version 2 of the SDK also let you customize the behaviour of the SDK by providing resource values in XML. Version 3 ignores these custom options from XML to simplify behaviour and improve performance. The recommended way to customize the Analytics client is to use the Builder methods instead.

Migrating to v4

Note: If you are using version 2 of the Android SDK, you’ll have to make few changes to get up and running with version 3.

In version 3, adding a Device-mode destination looks like this:

compile('com.segment.analytics.android:analytics-core:+') {
  transitive = true
}

// Add other dependencies as you want here
compile('com.segment.analytics.android:analytics-integration-google-analytics:+') {
  transitive = true
}
compile('com.segment.analytics.android:analytics-integration-mixpanel:+') {
  transitive = true
}
compile('com.segment.analytics.android:analytics-integration-quantcast:+') {
  transitive = true
}

or, if you wanted to use all Device-mode destinations:

compile('com.segment.analytics.android:analytics:+') {
  transitive = true
}

In version 4, the analytics-core artifact is not available any longer. It has been renamed to analytics (which previously packaged all Device-mode destinations). Version 4 of analytics only includes the Segment destination. Which means, to package a Device-mode destination, you must manually add that dependency.

compile 'com.segment.analytics.android:analytics:+'

compile('com.segment.analytics.android.integrations:google-analytics:1.0.0') {
  transitive = true
}
compile('io.branch.segment.analytics.android.integrations:library:1.0.0-RELEASE') {
  transitive = true
}

In addition to adding a dependency, you must point the Analytics-Android SDK to the destination.

Analytics analytics = new Analytics.Builder(context, writeKey)
  .use(GoogleAnalyticsIntegration.FACTORY)
  .use(BranchIntegration.FACTORY)
  ...
  .build();
val analytics = Analytics.Builder(context, writeKey)
  .use(GoogleAnalyticsIntegration.FACTORY)
  .use(BranchIntegration.FACTORY)
  ...
  .build()

This page was last modified: 14 Feb 2024



Get started with Segment

Segment is the easiest way to integrate your websites & mobile apps data to over 300 analytics and growth tools.
or
Create free account