> ## Documentation Index
> Fetch the complete documentation index at: https://docs.permutive.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Android TV

> Integrate Permutive on Android TV and Google TV using the Android SDK

<CardGroup cols={3}>
  <Card title="Quick Start" href="/sdks/mobile/android/getting-started/quick-start" icon="rocket" />

  <Card title="Video Tracking" href="#video-tracking" icon="video" />

  <Card title="Android SDK Reference" href="/sdks/mobile/android/overview" icon="book" />
</CardGroup>

## Overview

Android TV and Google TV applications use the **Permutive Android SDK**. The same SDK that powers mobile Android applications fully supports Android TV, providing identical APIs for tracking, identity management, and ad targeting.

<Info>
  **Same SDK, Same APIs:** The Permutive Android SDK works seamlessly on Android TV. All features documented in the [Android SDK](/sdks/mobile/android/overview) are available on Android TV.
</Info>

## Requirements

| Requirement | Version                    |
| ----------- | -------------------------- |
| Android API | 21+ (Android 5.0 Lollipop) |
| Compile SDK | 34+                        |
| Java        | 8+ (JVM target 1.8)        |
| Kotlin      | 1.6+ (if using Kotlin)     |

## Installation

Add the Permutive SDK to your `build.gradle`:

```kotlin theme={"dark"}
dependencies {
    // Core SDK (required)
    implementation("com.permutive.android:core:1.11.3")

    // Google Ads integration (optional)
    implementation("com.permutive.android:google-ads:2.2.0")
}
```

## Initialization

Initialize the SDK in your Application class:

```kotlin theme={"dark"}
import android.app.Application
import com.permutive.android.Permutive

class MyTVApplication : Application() {

    lateinit var permutive: Permutive
        private set

    override fun onCreate() {
        super.onCreate()

        permutive = Permutive.Builder(
            applicationContext = this,
            apiKey = "<your api key>",
            workspaceId = "<your workspace id>"
        ).build()
    }
}
```

For detailed initialization options, see [Android Initialization](/sdks/mobile/android/getting-started/initialization).

***

## Video Tracking

Video tracking on Android TV uses the `MediaTracker` API. This is the primary use case for CTV applications.

### Creating a MediaTracker

```kotlin theme={"dark"}
import com.permutive.android.MediaTracker

class VideoActivity : AppCompatActivity() {

    private val permutive by lazy {
        (application as MyTVApplication).permutive
    }

    private lateinit var videoTracker: MediaTracker

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        videoTracker = permutive.trackVideoView(
            durationMilliseconds = 3600000, // 1 hour
            videoProperties = MediaTracker.VideoProperties(
                title = "Show Title - S1E1",
                genre = listOf("Drama", "Thriller"),
                contentType = listOf("Series", "Episode"),
                seasonNumber = 1,
                episodeNumber = 1,
                runtime = 3600
            ),
            pageProperties = MediaTracker.PageProperties(
                title = "Now Playing",
                url = Uri.parse("https://example.com/shows/title/s1e1")
            )
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        videoTracker.stop() // Important: Always stop to send VideoComplete
    }
}
```

### Integrating with ExoPlayer

Android TV applications typically use ExoPlayer (now part of Media3) for video playback:

```kotlin theme={"dark"}
import com.permutive.android.MediaTracker
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.analytics.AnalyticsListener
import androidx.media3.common.Player

class VideoPlayerActivity : AppCompatActivity() {

    private val permutive by lazy {
        (application as MyTVApplication).permutive
    }

    private lateinit var videoTracker: MediaTracker
    private lateinit var exoPlayer: ExoPlayer

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_video_player)

        setupVideoTracker()
        setupExoPlayer()
    }

    private fun setupVideoTracker() {
        videoTracker = permutive.trackVideoView(
            durationMilliseconds = videoDurationMs,
            videoProperties = MediaTracker.VideoProperties(
                title = "Video Title",
                genre = listOf("Documentary"),
                contentType = listOf("Feature")
            )
        )
    }

    private fun setupExoPlayer() {
        exoPlayer = ExoPlayer.Builder(this).build()

        exoPlayer.addListener(object : Player.Listener {
            override fun onPlaybackStateChanged(state: Int) {
                when (state) {
                    Player.STATE_READY -> {
                        if (exoPlayer.isPlaying) {
                            videoTracker.play()
                        }
                    }
                    Player.STATE_BUFFERING -> {
                        videoTracker.pause()
                    }
                }
            }

            override fun onIsPlayingChanged(isPlaying: Boolean) {
                if (isPlaying) {
                    videoTracker.play()
                } else {
                    videoTracker.pause()
                }
            }
        })

        // Track seeking
        exoPlayer.addAnalyticsListener(object : AnalyticsListener {
            override fun onPositionDiscontinuity(
                eventTime: AnalyticsListener.EventTime,
                reason: Int
            ) {
                if (reason == Player.DISCONTINUITY_REASON_SEEK) {
                    videoTracker.play(exoPlayer.currentPosition)
                }
            }
        })
    }

    override fun onPause() {
        super.onPause()
        videoTracker.pause()
        exoPlayer.pause()
    }

    override fun onResume() {
        super.onResume()
        if (exoPlayer.isPlaying) {
            videoTracker.play()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        videoTracker.stop()
        exoPlayer.release()
    }
}
```

### MediaTracker Lifecycle

| Method             | Description                          | Events Tracked           |
| ------------------ | ------------------------------------ | ------------------------ |
| `play()`           | Start/resume tracking                | `Videoview` (first call) |
| `play(positionMs)` | Start at specific position (seeking) | -                        |
| `pause()`          | Pause tracking (buffering, paused)   | -                        |
| `stop()`           | End tracking permanently             | `VideoComplete`          |

<Warning>
  **Always call `stop()`:** Failing to call `stop()` when the video ends or the user exits will prevent `VideoComplete` events from being tracked.
</Warning>

For complete MediaTracker documentation, see [Android Video Tracking](/sdks/mobile/android/features/video-tracking).

***

## Video Properties

The SDK provides standard video properties for consistent tracking:

```kotlin theme={"dark"}
MediaTracker.VideoProperties(
    title = "Video Title",
    genre = listOf("Action", "Thriller"),
    contentType = listOf("Movie", "Feature"),
    ageRating = "PG-13",
    runtime = 7200, // Runtime in seconds
    country = "US",
    originalLanguage = "en",
    audioLanguage = "en",
    areSubtitlesEnabled = true,
    subtitlesLanguage = "en",
    seasonNumber = 1,
    episodeNumber = 5,
    consecutiveEpisodes = 3,
    iabCategories = listOf("IAB1", "IAB2")
)
```

***

## Video Ad Tracking

Track video advertisements within your content:

```kotlin theme={"dark"}
// When ad starts
val adTracker = videoTracker.trackAdView(
    durationMs = 30000, // 30 second ad
    adProperties = AdTracker.AdProperties(
        title = "Product Ad",
        durationInSeconds = 30,
        campaignId = "campaign_123",
        creativeId = "creative_456"
    )
)

adTracker.play()

// When ad completes
adTracker.completion()
```

See [Android Video Ad Tracking](/sdks/mobile/android/features/video-ad-tracking) for details.

***

## Identity Management

Set user identities for cross-device tracking:

```kotlin theme={"dark"}
// userId: Your application's user identifier
// hashedEmail: SHA256 hash of the user's email address
permutive.setIdentity(
    listOf(
        Alias.create("user_id", userId, priority = 0),
        Alias.create("email_sha256", hashedEmail, priority = 1)
    )
)
```

See [Android Identity Management](/sdks/mobile/android/core-concepts/identity-management) for details.

***

## Cohorts and Targeting

### Accessing Cohorts

```kotlin theme={"dark"}
// Get all cohorts
val cohorts = permutive.cohorts

// Get activations for a specific ad platform
val gamActivations = permutive.activations("gam")
```

### Google Ad Manager Integration

```kotlin theme={"dark"}
import com.permutive.android.googleads.addPermutiveTargeting

val adRequest = AdManagerAdRequest.Builder()
    .addPermutiveTargeting(permutive)
    .build()

adView.loadAd(adRequest)
```

See [Android Google Ad Manager](/sdks/mobile/android/integrations/google-ad-manager) for complete integration details.

***

## Android TV-Specific Considerations

<AccordionGroup>
  <Accordion title="Leanback UI">
    Android TV uses the Leanback library for its 10-foot UI. Ensure your tracking implementation doesn't interfere with Leanback components:

    ```kotlin theme={"dark"}
    class VideoFragment : VideoSupportFragment() {

        private lateinit var videoTracker: MediaTracker

        override fun onStart() {
            super.onStart()
            // VideoSupportFragment handles player lifecycle
            // Just sync tracking with player state
        }
    }
    ```
  </Accordion>

  <Accordion title="D-pad Navigation">
    Android TV uses D-pad navigation. Tracking works independently of navigation, but ensure you handle the back button appropriately:

    ```kotlin theme={"dark"}
    override fun onBackPressed() {
        // Stop tracking before navigating away
        videoTracker.stop()
        super.onBackPressed()
    }
    ```
  </Accordion>

  <Accordion title="Picture-in-Picture">
    If your app supports PiP mode, continue tracking during PiP:

    ```kotlin theme={"dark"}
    override fun onPictureInPictureModeChanged(
        isInPictureInPictureMode: Boolean,
        newConfig: Configuration
    ) {
        super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
        // Continue tracking - no changes needed
        // MediaTracker tracks independently of UI mode
    }
    ```
  </Accordion>

  <Accordion title="Android Advertising ID">
    Android TV supports AAID. Use the AAID provider for automatic advertising ID tracking:

    ```kotlin theme={"dark"}
    dependencies {
        implementation("com.permutive.android:aaid-provider:1.11.3")
    }
    ```

    ```kotlin theme={"dark"}
    val permutive = Permutive.Builder(this, apiKey, workspaceId)
        .enableAaidProvider()
        .build()
    ```

    See [AAID Provider](/sdks/mobile/android/integrations/aaid-provider) for details.
  </Accordion>

  <Accordion title="Background Playback">
    Android TV apps may continue video playback when the home button is pressed. Handle this appropriately:

    ```kotlin theme={"dark"}
    override fun onStop() {
        super.onStop()
        if (!isChangingConfigurations) {
            // User left the app
            if (exoPlayer.isPlaying) {
                // Playback continues in background
                // Keep tracking active
            } else {
                videoTracker.pause()
            }
        }
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Best Practices

<Tabs>
  <Tab title="Do">
    * Initialize SDK early in Application.onCreate()
    * Create MediaTracker when video is ready to play
    * Call `stop()` when video ends or user exits
    * Sync `play()`/`pause()` with actual player state
    * Handle buffering states with `pause()`
    * Include video metadata for richer cohorts
    * Use Leanback-compatible patterns
  </Tab>

  <Tab title="Don't">
    * Don't create multiple MediaTrackers simultaneously
    * Don't forget to call `stop()` when done
    * Don't skip the duration parameter
    * Don't block the main thread with SDK calls
    * Don't send PII in event properties
    * Don't interfere with Leanback focus handling
  </Tab>
</Tabs>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="SDK not initializing">
    **Problem:** Permutive instance is null or initialization fails.

    **Solutions:**

    * Verify API key and workspace ID are correct
    * Ensure initialization happens in Application.onCreate()
    * Check for initialization errors in Logcat
    * Enable debug mode: `permutive.setDeveloperMode(true)`
  </Accordion>

  <Accordion title="Events not appearing in dashboard">
    **Problem:** Video events don't show in Permutive dashboard.

    **Solutions:**

    * Verify MediaTracker was created successfully
    * Ensure `play()` is called when video starts
    * Ensure `stop()` is called when video ends
    * Wait 5-10 minutes for events to process
    * Check Logcat for "Accepted: 1 / 1" messages
  </Accordion>

  <Accordion title="Engagement time incorrect">
    **Problem:** Engagement metrics don't match expected values.

    **Solutions:**

    * Sync `play()`/`pause()` calls with actual player state
    * Call `pause()` during buffering
    * Provide accurate duration when creating MediaTracker
  </Accordion>

  <Accordion title="VideoComplete not tracked">
    **Problem:** VideoComplete events not appearing.

    **Solutions:**

    * Ensure `stop()` is called in `onDestroy()`
    * Handle back button to call `stop()` before navigation
    * Verify app isn't killed before event sends
  </Accordion>
</AccordionGroup>

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Android SDK Overview" icon="android" href="/sdks/mobile/android/overview">
    Complete Android SDK documentation
  </Card>

  <Card title="Android Video Tracking" icon="video" href="/sdks/mobile/android/features/video-tracking">
    Detailed MediaTracker documentation
  </Card>

  <Card title="Android Video Ad Tracking" icon="rectangle-ad" href="/sdks/mobile/android/features/video-ad-tracking">
    Video advertisement tracking
  </Card>

  <Card title="CTV Video Best Practices" icon="play" href="/sdks/ctv/video-tracking">
    Cross-platform video tracking guide
  </Card>
</CardGroup>
