---
updatedAt: 2026-04-27T11:29:53.000Z
agentTools:
  siteIndex: https://developer.bitmovin.com/llms.txt
  projectIndex: https://developer.bitmovin.com/playback/llms.txt
---

# Android Collector

This guide describes how to set up the Android Collector v3. You can find a guide for the deprecated v2 collector [here](https://developer.bitmovin.com/playback/docs/setup-analytics-android).

# How to set up Analytics on Android

The Bitmovin Player for Android includes Analytics pre-integrated. Players like ExoPlayer, Media3 ExoPlayer, THEOplayer and the Amazon IVS player can be tracked through our player-specific collectors.

In order to complete this guide, you need at least a basic setup of your chosen player. If you haven't set up your Player yet, go to the corresponding Player documentation page first: [Bitmovin Player getting started guide](https://developer.bitmovin.com/playback/docs/getting-started-android), [ExoPlayer documentation](https://github.com/google/ExoPlayer), [Media3 ExoPlayer documentation](https://github.com/androidx/media), [Amazon IVS Player documentation](https://docs.aws.amazon.com/ivs/latest/userguide/player-android.html), [THEOplayer documentation](https://optiview.dolby.com/docs/theoplayer/android/).

You also need to set up your analytics license and allowlist your domain. If you haven't done this yet, go to our [How to Set Up](https://developer.bitmovin.com/playback/docs/setup-analytics) page and follow the steps there.

### Platform requirements:

All Collectors support Android 6+

# Bitmovin Player

## Step 1: Configure Analytics

Starting with version `3.41.0` of the player, Analytics comes pre-integrated in the player. You just need to enable Analytics during creation of the Player.

#### Enable Analytics for the Player

For a minimal setup, only the license key needs to be specified. For more analytics configuration see [here](https://developer.bitmovin.com/playback/docs/configuration-analytics).\
This minimal setup is enough to enable basic tracking.

```kotlin
val playerConfig = PlayerConfig()
val analyticsConfig = AnalyticsConfig(licenseKey = "<LICENSE_KEY>")
val player = Player(context, playerConfig, AnalyticsPlayerConfig.Enabled(analyticsConfig))
```

#### Enrich analytics data with Metadata

In order to enrich analytics with more data, `DefaultMetadata` and `SourceMetadata` can be set.

`DefaultMetadata` can be set during player creation, and this contains source independent data.

```kotlin
val defaultMetadata = DefaultMetadata(
  	customUserId = "userId",
  	customData = CustomData(customData1 = "appVersion4")
  )

val player = Player(
  context,
  playerConfig,
  AnalyticsPlayerConfig.Enabled(analyticsConfig, defaultMetadata),
)
```

`SourceMetadata` can be set for each source to add more source-specific metadata.

```kotlin
val sourceMetadata = SourceMetadata(
  	title = "stream title",
  	videoId = "exampleId"	,
  	customData = CustomData(customData2 = "ExampleGenre")
  )

val source = Source(sourceConfig, AnalyticsSourceConfig.Enabled(sourceMetadata))
player.load(source)
```

## Step 2: Check Statistics in Dashboard

After the setup is done there's nothing more to do. Events are recorded automatically and you can head over to the [Analytics Dashboard](https://bitmovin.com/dashboard/analytics/audience) to see your metrics.

# 3rd Party Players

## Step 1: Add the SDK to Your Project.

#### Add the Bitmovin release repository to your project

Add a link to our release repository to your application's `build.gradle` file. In addition to that, the Google maven repository must be added.

```groovy build.gradle
allprojects {
    repositories {
        mavenCentral()
        google()

        maven {
            url 'https://artifacts.bitmovin.com/artifactory/public-releases'
        }
    }
}
```

#### Add the Dependency to the Project

Add the Bitmovin Analytics Android SDK as a dependency to your main project's `build.gradle` file as shown below, while replacing `{Version Number}` with the desired SDK version number. The available SDK versions are listed in our [Release Notes](https://developer.bitmovin.com/playback/docs/analytics-collector-android-releases). We recommend to always stay up to date with both player and collector versions. However if you are using an older player version, check out which collector version you should use at our  [Android Collector Github page](https://github.com/bitmovin/bitmovin-analytics-collector-android#getting-started).

```groovy Media3 ExoPlayer
dependencies {
    implementation 'com.bitmovin.analytics:collector-media3-exoplayer:{Version Number}'
}
```
```Text THEOplayer
dependencies {
    implementation 'com.bitmovin.analytics:collector-theoplayer:{Version Number}'
}
```
```groovy ExoPlayer
dependencies {
    implementation 'com.bitmovin.analytics:collector-exoplayer:{Version Number}'
}
```
```groovy IVS Player
dependencies {
    implementation 'com.bitmovin.analytics:collector-amazon-ivs:{Version Number}'
}
```

## Step 2: Setup the Collector

First create a basic `AnalyticsConfig` object with your Analytics License key. You can further customise it by adding optional configuration parameters. For more information and a complete list of configuration fields see our [Configuration Guide](https://developer.bitmovin.com/playback/docs/configuration-analytics).

Please replace `ANALYTICS_LICENSE_KEY` with a license key from your account. Please checkout [How to set up](https://developer.bitmovin.com/playback/docs/setup-analytics)  to learn more about how to get to your analytics license.

Create the collector object by passing the config object. Finally attach your player to the collector. Always detach your player from the collector once you are done, e.g. when calling the `player.release()` method.

```kotlin Media3 ExoPlayer
// Create a AnalyticsConfig using your Bitmovin analytics license key
val analyticsConfig = AnalyticsConfig("<ANALYTICS_LICENSE_KEY>")

// Create Analytics Collector for Media3 ExoPlayer
val analyticsCollector = IMedia3ExoPlayerCollector.Factory.create(applicationContext, analyticsConfig)

// create and set SourceMetadata
val sourceMetadata = SourceMetadata(title = "exampletitle", videoId = "exampleId")
analyticsCollector.sourceMetadata = sourceMetadata

// Attach your Media3 ExoPlayer instance
analyticsCollector.attachPlayer(player)

// set mediaItem and start playing video after attaching
player.setMediaItem(mediaItem)
player.prepare()
player.play()

// Detach your player when you are done. 
// For example, call this method before releasing the player
analyticsCollector.detachPlayer()
```
```Text THEOplayer
// Create a AnalyticsConfig using your Bitmovin analytics license key
val analyticsConfig = AnalyticsConfig("<ANALYTICS_LICENSE_KEY>")

// Create Analytics Collector for THEOplayer
val analyticsCollector = ITHEOplayerCollector.create(applicationContext, analyticsConfig)

// create and set SourceMetadata
val sourceMetadata = SourceMetadata(title = "exampletitle", videoId = "exampleId")
analyticsCollector.sourceMetadata = sourceMetadata

// Attach your THEOplayer instance
analyticsCollector.attachPlayer(player)

// set source and start playing video after attaching
player.source = exampleSource
player.play()

// Detach your player when you are done. 
// For example, call this method before releasing the player
analyticsCollector.detachPlayer()
```
```kotlin ExoPlayer
// Create a AnalyticsConfig using your Bitmovin analytics license key
val analyticsConfig = AnalyticsConfig("<ANALYTICS_LICENSE_KEY>")

// Create Analytics Collector for ExoPlayer
val analyticsCollector = IExoPlayerCollector.Factory.create(applicationContext, analyticsConfig)

// create and set SourceMetadata
val sourceMetadata = SourceMetadata(title="exampletitle", videoId="exampleId")
analyticsCollector.sourceMetadata = sourceMetadata

// Attach your ExoPlayer instance
analyticsCollector.attachPlayer(player)

// set mediaItem and start playing video after attaching
player.setMediaItem(mediaItem)
player.prepare()
player.play()

// Detach your player when you are done. 
// For example, call this method before releasing the player
analyticsCollector.detachPlayer()
```
```kotlin IVS Player
// Create an AnalyticsConfig using your Bitmovin analytics license key
val analyticsConfig = AnalyticsConfig("<ANALYTICS_LICENSE_KEY>")

// Create Analytics Collector for Amazon IVS Player
val analyticsCollector = IAmazonIvsPlayerCollector.Factory.create(applicationContext, analyticsConfig)

// create and set SourceMetadata
val sourceMetadata = SourceMetadata(title="exampletitle", videoId="exampleId")
analyticsCollector.sourceMetadata = sourceMetadata

// Attach your Amazon IVS Player instance
analyticsCollector.attachPlayer(player)

// load and start playing video after attaching
player.load(sourceUri)
player.play()

// Detach your player when you are done.
// For example, call this method before releasing the player
analyticsCollector.detachPlayer()
```

When switching to a new video we recommend that you follow the sequence of events below.

```kotlin Media3 ExoPlayer / ExoPlayer
// Detach the player when the first video is completed
analyticsCollector.detachPlayer()

// change SourceMetadata
val sourceMetadata2 = SourceMetadata(title = "exampletitle2", videoId = "exampleId2")
analyticsCollector.sourceMetadata = sourceMetadata2

// change the source on the player
player.setMediaItem(mediaItem2)

// Reattach your player instance
analyticsCollector.attachPlayer(player)
player.prepare()
player.play()
```
```Text THEOplayer
// Detach the player when the first video is completed
analyticsCollector.detachPlayer()

// change SourceMetadata
val sourceMetadata2 = SourceMetadata(title = "exampletitle2", videoId = "exampleId2")
analyticsCollector.sourceMetadata = sourceMetadata2

// change the source on the player
player.source = exampleSource2

// Reattach your player instance
analyticsCollector.attachPlayer(player)
player.play()
```
```kotlin IVS Player
// Detach the player when the first video is completed
analyticsCollector.detachPlayer()

// change SourceMetadata
val sourceMetadata2 = SourceMetadata(title = "exampletitle2", videoId = "exampleId2")
analyticsCollector.sourceMetadata = sourceMetadata2

// change the source on the player
player.load(exampleSource2)

// Reattach your player instance
analyticsCollector.attachPlayer(player)
player.play()
```

## Step 3: Check Statistics in Dashboard

After the setup is done there is nothing more to do. Events are recorded automatically and you can head over to the [Analytics Dashboard](https://bitmovin.com/dashboard/analytics/audience) to see statistics.

# Threading Model

The collector API is not thread safe. All calls need to come from the same thread as the player is executed on (usually the MainThread). While the collector might not crash when called from different threads, it can lead to inconsistent data.

# Minification / Obfuscation

The collector uses `kotlinx.serialization` to serialize/deserialize DTOs starting with version `3.15.0`.\
This makes proguard rules obsolete and therefore the collector is not shipped with any consumer-proguard rules anymore.

If the API is called through reflection (for example for React Native Wrappers), the following rule is needed:

```
-keep class com.bitmovin.analytics.api.** { *; }
```

<br />

Please reach out to us if there are any issues.

# Common Integration Pitfalls

### Media3-Exoplayer

#### AbstractMethodError in media3 AnalyticsListener

Depending on the Release Configuration, Default Methods of media3 AnalyticsListener might be stripped away, which leads to an `AbstractMethodError` with a StackTrace similar to below:

```java Java
java.lang.AbstractMethodError: abstract method "void androidx.media3.exoplayer.analytics.AnalyticsListener.onPlayerStateChanged(androidx.media3.exoplayer.analytics.AnalyticsListener$EventTime, boolean, int)"
at androidx.media3.exoplayer.analytics.DefaultAnalyticsCollector.lambda$onPlayerStateChanged$36(DefaultAnalyticsCollector.java:549)
at androidx.media3.exoplayer.analytics.DefaultAnalyticsCollector$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0)
at androidx.media3.common.util.ListenerSet$ListenerHolder.invoke(ListenerSet.java:339)
```

To fix the issue the following gradle setting needs to be applied in the `gradle.properties` file:

```java gradle.properties
android.useFullClasspathForDexingTransform = true
```

This issue arises due to a bug with desugaring and default Methods of Kotlin/Java.\
Reference: <https://issuetracker.google.com/issues/230454566>

# Examples

You can find fully functional code examples in our [Github Repository](https://github.com/bitmovin/bitmovin-analytics-collector-android/tree/main/collector-bitmovin-player-example).