AndroidTV

From Engineering Client Portal

Engineering Portal / Digital/ DCR & DTVR / AndroidTV

Introduction

This guide provides step-by-step instructions for integrating the Nielsen Android AppSDK into Android TV application.

The SDK supports three measurement types: DCR  Video (Digital Content Ratings) for measuring VOD and live streaming video content by tracking playhead position during playback, DCR Static for measuring non-video content such as web views, articles, and informational screens, and DTVR (Digital TV Ratings) for measuring live streams by processing Nielsen ID3 watermarks embedded in the broadcast signal.

Step 1: Android AppSDK Integrations into Android TV App

This steps covers the complete integration process including AppSDK initialization, content metadata configuration, playhead tracking, ID3 tag processing, and user opt-out/in implementation.

1.1: Add Nielsen AppSDK Dependency

Add the Nielsen Android AppSDK Jar maven dependency to the App module and configure build.gradle.

build.gradle (app level)

dependencies {
    implementation 'com.nielsenappsdk.global:ad:10.2.0.0'
    implementation 'com.google.android.gms:play-services-ads-identifier:18.2.0'
    implementation "androidx.work:work-runtime:2.11.2"
}

1.2: Configure Android AppSDK Parameters

Build the JSON configuration with Nielsen credentials.

val config = JSONObject()
    .put("appid", "NIELSEN_APP_ID")         // Nielsen-provided App ID  [required]
    .put("sfcode", "cert")                  // cert for testing, [Optional]
    .put("clientid", "client_id")           // Client identifier [Optional]
    .put("vcid", "vcid")                    // vendor client id [Optional]
    .put("prod", "dcrvideo")                // Product codes [Optional]
    .put("category", "category")            // App category [Optional]
    .put("nol_devDebug", "DEBUG")           // Remove in production     
    .put("uid2", "unified_id_value")        // UID2 identifier [Optional]
    .put("hem_sha256", "hashed_email")      // Hashed email [Optional]

1.3: Initialize Android AppSDK

The following example code is for creating a singleton manager and initializing the Android AppSDK when the app starts.

private var mAppSdk: AppSdk? = null

fun initializeAppSdk(context: Context, config: JSONObject) {
    mAppSdk = AppSdk(context, config, object : IAppNotifier {
        override fun onAppSdkEvent(timestamp: Long, code: Int, description: String?) {
            if (code == AppSdk.EVENT_STARTUP) {
                Log.d("Nielsen", "AppSdk initialized successfully")
            }
        }
    })
    
    if (mAppSdk?.isValid != true) {
        Log.e("Nielsen", "Failed to initialize AppSdk")
    }
}

1.4: DCR Video - Start Measurement

The following example code is for Call play() and loadMetadata when video playback begins.

fun appStartMeteringVideo(video: Video) {
    // Build content metadata
    val metaData = JSONObject()
        .put("type", "content")               // type of content [required]
        .put("assetid", "uniqueassetid")      // unique ID for each asset [required]
        .put("program", "Program Name")       // name of program [required]
        .put("title", "Episode Title")        // ex: S1E3 [required]
        .put("length", "3600")                // length of content [required]
        .put("category", "Entertainment")     // content category [required]
        .put("adModel", "2")                  // 1=linear, 2=dynamic [required]
    
    // Build channel information
    val channelInfo = JSONObject()
        .put("channelName", "channelName")
        .put("mediaURL", "videoUrl")
    
    // Start measurement
    mAppSdk?.play(channelInfo)
    mAppSdk?.loadMetadata(metaData)
}


Reporting playhead position every 1 second during active playback.

fun monitorPlayhead(exoPlayer: ExoPlayer) {
    monitorJob = lifecycle.coroutineScope.launch(Dispatchers.Main) {
      var ticks = 0
        while (isActive) {
            if (exoPlayer.isPlaying) {
                val positionMs = exoPlayer.currentPosition
                val durationMs = exoPlayer.duration
                
                ticks++
               // Report every 1 second (since loop runs every 500ms)
                if (ticks % 2 == 0) {
                val playheadToReport: Long = if (videoDuration <= 0) {
                     System.currentTimeMillis() / 1000  // Live: UTC time
                  } else {
                     videoPosition.toLong()  // VOD: Position from start
                   }
              
                mAppSdk?.setPlayheadPosition(playheadSeconds)
            }
            delay(500)
        }
    }
}

1.5: DCR Video - Stop/End Measurement

The following example code is for Signal playback state changes for accurate measurement.

Pause Playback :

fun appStopMeteringVideo() {
    mAppSdk?.stop()
}


End Content Session (Video End) :

fun appEndMeteringVideo() {
    mAppSdk?.end()
}


Close SDK (App Exit Only) :

fun appCloseMeteringVideo() {
    mAppSdk?.close()
    mAppSdk = null
}

1.6: DCR Static - Web Content Measurement

The following example code is for measuring non-video content like WebViews and articles.

Start Static Measurement :

fun staticLoadMetadata() {
    val metadata = JSONObject()
        .put("type", "static")                    // type of content [required]
        .put("section", "Web View Screen")        // section of site [required]
        .put("segA", "CustomSegmentA")            // custom segment [optional]
        .put("segB", "CustomSegmentB")            // custom segment [optional]
        .put("segC", "CustomSegmentC")            // custom segment [optional]
        .put("crossId1", "Standard Episode ID")   // [optional]
        .put("crossId2", "Content Originator")    // [optional]
    
    mAppSdk?.loadMetadata(metadata)
}


End Static Measurement :

fun staticEnd() {
    mAppSdk?.staticEnd()
}

1.7: DTVR - ID3 Tag Processing

The following example code is for processing Nielsen ID3 watermarks from live TV streams for DTVR measurement.

Listen for ID3 Metadata (ExoPlayer) :

inner class PlayerEventListener : Player.Listener {
    override fun onMetadata(metadata: Metadata) {
        for (i in 0 until metadata.length()) {
            val entry = metadata.get(i)
            if (entry is PrivFrame) {
                val owner = entry.owner
                val data = String(entry.privateData, Charsets.UTF_8)
                
                // Check if it's a Nielsen ID3 tag
                if (owner.contains("nielsen", ignoreCase = true) ||
                    owner.contains("www.nielsen.com", ignoreCase = true)) {
                    appProcessID3tag(owner + data)
                }
            }
        }
    }
}


Send ID3 Tag to Nielsen SDK :

fun appProcessID3tag(id3String: String?) {
    try {
        mAppSdk?.sendID3(id3String)
    } catch (e: Exception) {
        Log.e("Nielsen", "Cannot process ID3 tag: ${e.message}")
    }
}

1.8: User Opt-Out Implementation

The following example code is to provide users the ability to opt out of Nielsen measurement via WebView.

Get Opt-Out URL :

fun getOptOutUrl(): String {
    return mAppSdk?.userOptOutURLString() ?: ""
}
// Load this URL in a WebView
webView.loadUrl(getOptOutUrl())


Handle Opt-Out Response :

webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
        val url = request.url.toString()
        
        // Check for Nielsen opt-out response
        if (url.startsWith("nielsenappsdk://")) {
            mAppSdk?.userOptOut(url)
            // Navigate back or show confirmation
            return true
        }
        return false
    }
}


Check Opt-Out Status :

fun getOptOutStatus(): Boolean {
    return mAppSdk?.optOutStatus ?: false
}

1.9: Android AppSDK Getter Methods

These methods provide information like Android AppSDK Version, NielsenId details.

Get Nielsen ID :

fun getNielsenId(): String = mAppSdk?.nielsenId ?: ""

Get Device ID :

fun getDeviceId(): String = mAppSdk?.deviceId ?: ""

Get Demographic ID :

fun getDemographicId(): String = mAppSdk?.demographicId ?: ""

Get SDK Meter Version :

fun getMeterVersion(): String = AppSdk.getMeterVersion()

Step 2: Quick Reference - Android AppSDK Methods

The table below provides a summary of the core Android AppSDK methods, their primary functions, and the appropriate triggers for calling them within your application lifecycle.

Method Purpose When to Call
play(channelInfo) Start content session Video playback begins.
loadMetadata(metadata) Send content/Ad/static info After play API call or for static content.
setPlayheadPosition(video playback pos) Report playhead position setPlayheadPosition(pos) - sets the playhead position in AppSDK as video playback time (seconds) in the content (VOD Video On Demand) or the current UTC time for live stream.
sendID3(tag) Process DTVR videos When ID3 tag received from stream.
stop() Pause measurement Video paused.
end() End content session Video playback ends.
staticEnd() End static session Leave static content screen.
close() Destroy SDK instance App exit only.
userOptOutURLString() Get opt-out URL Display opt-out WebView.
userOptOut(url) Set opt-out preference When the user completes the opt-out.

Step 3: Sample App: Download, Build, and Emulator Setup

The following section provides instructions for downloading the sample application, building the APK within Android Studio, and setting up the necessary Android TV emulator environment for testing.

3.1: Download the package here

Click here to  download the project and open the project in Android Studio IDE.

3.2: Build the APK from this Project

Before building the apk, create an AndroidTV emulator from the IDE and install the App directly through Android Studio.

Follow the steps to test AndroidTV sample Apps in TV Emulators and how to build the app from the client package.

3.3: Create the Android TV Emulator

To create an Android TV emulator, you primarily use Android Studio to set up an Android Virtual Device (AVD).

Step 4: Install the AndroidTV sample video player App

Once you have built the APK and configured your Android TV emulator, use either of the following methods to install the sample video player application.

Method 1: Drag and Drop (Easiest)

Use your mouse to drag and drop the APK onto the running emulator :

  1. Launch the Android TV emulator.
  2. Locate the .apk file on your computer.
  3. Drag the file and drop it directly onto the emulator window.
  4. Wait for the installation to automatically complete.


Method 2 : Use ADB (Command Line)

Use the Android Debug Bridge (ADB) if you have the Android SDK Platform-Tools installed :

  1. Open the terminal or command prompt.
  2. Ensure emulator is running and detected by typing: -> adb devices.
  3. Install the APK by running the following command: -> adb install path/to/your/sample_app.apk.

Step 5: Open up Android TV Emulator

After installing the sample app, follow these steps to launch the Nielsen Sample TV application on your emulator.

Select Nielsen Sample TV App  -> Select Legacy Option

Screenshot 20260527 133449.png
Screenshot 20260527 133705.png
Screenshot 20260527 134418.png
Screenshot 20260529 152139.png

Setting page for  Select  Opt out/in options

Screenshot 20260527 134647.png

Next Steps

If there are any questions or concerns then please reach out to the AppSDK team. Reference the following guides for product specific information :

For further technical details , please contact your Technical Account Manager (TAM).