DCR Static Android SDK: Difference between revisions

From Engineering Client Portal

No edit summary
 
(11 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR & DTVR}}  {{CurrentBreadcrumb}}
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|US DCR & DTVR}}  {{CurrentBreadcrumb}}
[[Category:Digital]]
[[Category:Digital]]


=== Prerequisites ===
== Overview ==
To start using the App SDK, the following items are required:
This guide covers DCR Static Only Implementation information for the Nielsen SDK.  If implementation measurement for Video, please refer to our [[DCR_Video_Android_SDK|Video Guide]].
 
{{Android_Prerequisites}}
 
__TOC__
{{Android_Implementation}}
 
== SDK Initialization ==
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated prior to version 5.1.1. (Version 4.0 for Android)
 
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.
{| class="wikitable"
{| class="wikitable"
|-
|-
! style="width: 30px;" |
! Parameter / Argument !! Description !! Source !! Required? !! Example
! style="width: 15%;" | Item
! Description
! Source
|-
|-
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen
| appid || Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. || Nielsen-specified || Yes || PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|-
|-
|| || '''sfcode''' || Environment that the SDK must point to || Contact Nielsen
| nol_devDebug || Enables Nielsen console logging. Only required for testing
|-
|| Nielsen-specified || Optional || "DEBUG"
|| ☑ || '''Nielsen SDK''' || Includes SDK libraries and '''sample implementation'''; ''See [[Android SDK Release Notes]]'' || [[Special:Downloads|Download]]
|}
|}
If you do not have any of these pre-requisites or if you have any questions, please contact our SDK sales support team.
Refer to [[Digital Measurement Onboarding]] guide for more information on how to get a Nielsen App SDK and appid.


=== Import Library ===
== Debug flag for development environment ==
Refer to [[Android SDK API Reference#Setting Up Development Environment|Android SDK API Reference - Setting Up Development Environment]] for information on importing libraries.
Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag,
* The latest version of App SDK allows instantiating multiple instances of App SDK object and can be used simultaneously without any issues.
Pass the argument <code>@"nol_devDebug":@"INFO"</code>, in the JSON string . The permitted values are:
<blockquote>Note: The latest version of App SDK contains only appsdk.jar file and does not feature any native shared libraries like libAppSdk.so.</blockquote>
 
<blockquote>Note: The integrator should always tag the landing page on the app.</blockquote>
* '''INFO''': Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.
* '''WARN''': Indicates potential integration / configuration errors or SDK issues.
* '''ERROR''': Indicates important integration errors or non-recoverable SDK issues.
* '''DEBUG''': Debug logs, used by the developers to debug more complex issues.
 
Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.
<blockquote>'''Note''': DO NOT activate the Debug flag in a production environment.</blockquote>
 
==== Sample SDK Initialization Code ====
[[AppSDK()]] is no longer a singleton object and should be initialized as below.
 
'''Initialization of App SDK object through a JSON object'''
<syntaxhighlight lang="java">try
{
  // Prepare AppSdk configuration object (JSONObject)
  JSONObject appSdkConfig = new JSONObject()
          .put("appid", "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA")
          .put("nol_devDebug", "DEBUG"); // only for debug builds
 
// Pass appSdkConfig to the AppSdk constructor
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);
}
catch (JSONException e)
{
  Log.e(TAG, "Couldn’t prepare JSONObject for appSdkConfig", e);
}
</syntaxhighlight>
Here, <code>appContext</code> is the App context object and <code>appSdkConfig</code> is JSON object for holding the parameters (<code>appid</code>) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.


=== Initialize SDK ===
 
Initialize App SDK as soon as the application is launched. Refer to [[iOS SDK API Reference#Initialization|Initalization]] for details on initializing an AppSDK object and the parameters required.
The integration of Nielsen App SDK will depend on type of client app.<br />
* Ensure that SDK files (AppSdk.jar and libAppSdk.so [App SDK 1.2 Only]) are included under the App’s project and the App SDK is linked to the App (the setting to link App SDK to the App can be found on property page of the App’s project).


=== Configure API calls - play ===
=== Configure API calls - play ===
Line 57: Line 89:
[[File:Sdk_dataflow.jpg]]
[[File:Sdk_dataflow.jpg]]


== Handling Foreground and Background states of App ==
=== Configure Metadata ===
Map the Nielsen keys to variables so that the content metadata is dynamically updated.
 
The Nielsen reserved keys are:
{| class="wikitable"
|-
! Key !! Description !! Data Type !! Value !! Required?
|-
| type || asset type || fixed || <code>'static'</code> || Yes
|-
| assetid || Unique ID for each article || dynamic || custom <br>(no [[Special Characters]]) || No
|-
| section || section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values || dynamic || custom || Yes
|-
| segA || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No
|-
| segB || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No
|-
| segC || custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) || dynamic || custom || No
|}
 
The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B & C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.
 
'''Aggregation Limits'''
There are limits on the number of unique values that can be aggregated on in reporting. The specific limitations by key are:
{| class="wikitable"
|-
! Key !! Aggregation Limit
|-
| section || maximum of 25 unique values (section <= 25)
|-
| segA || Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)
|-
| segB || Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)
|-
| segC || Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)
|}
 
=== DCR Static Duration Measurement per Section/Page/Asset ===
If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded ''with associated loadMetadata call having a different '''section name''' from the previous page''. If a new loadMetadata call is made with the same '''section name''', it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same '''section name''' (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views. <br>
<span class="mw-customtoggle-myDivisionDiag" style="color: cornflowerblue"> Show flow diagram for above description </span>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-myDivisionDiag">
[[File:DCRstaticflow.png|500px]]
</div>
<br>
'''Example 1''' - In this example, a static view and duration ping with duration=25 will be generated for "SPORTS" section.
<br>
<span class="mw-customtoggle-myDivisionJ1" style="color: cornflowerblue"> Show Android Java Example </span>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-myDivisionJ1">
<syntaxhighlight lang="Java">
JSONObject staticMetadataSports = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","SPORTS");
nielsenSDK.loadMetadata(staticMetadataSports);
       
      //in this example, after 25 seconds, new metadata is loaded for section "MOVIES"                 
 
JSONObject staticMetadataMovies = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","MOVIES");
nielsenSDK.loadMetadata(staticMetadataMovies);
</syntaxhighlight>
</div>
<br>
'''Example 2''' - In this example,, let's assume 20 seconds after the page is viewed, the app goes to background. A static duration ping with duration=20 will be generated for "SPORTS" section.
<br>
<span class="mw-customtoggle-myDivisionJ2" style="color: cornflowerblue"> Show Android Java Example </span>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-myDivisionJ2">
<syntaxhighlight lang="Java">
JSONObject staticMetadataSports = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","SPORTS");
nielsenSDK.loadMetadata(staticMetadataSports);       
 
  //App goes to background or killed after 20 seconds.
 
</syntaxhighlight>
</div>
 
'''Note:''' Once the app is returned to foreground or relaunched, the app needs to pass static metadata again in order to restart measuring DCR Static duration.
<br>
<br>
'''Example 3''' - Here we wish to generate a new view event and start a new duration timer even though the section name in the metadata is the same.
<br>
<span class="mw-customtoggle-myDivisionJ3" style="color: cornflowerblue"> Show Android Java Example </span>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-myDivisionJ3">
<syntaxhighlight lang="Java">
JSONObject staticMetadataSports = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","SPORTS");
staticMetadataSports.put("assetid","TENNIS");
nielsenSDK.loadMetadata(staticMetadataSports);
//in this example, after 25 seconds, we pass staticEnd before new metadata is loaded for section "SPORTS", but assetid "CRICKET"
 
 
nielsenSDK.staticEnd();
 
JSONObject staticMetadataSports = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","SPORTS");
staticMetadataSports.put("assetid","CRICKET");
nielsenSDK.loadMetadata(staticMetadataSports);
</syntaxhighlight>
</div>
 
'''Note:''' Even though the assetid has changed, a new view event would not be recognized unless staticEnd() is called in between loadMetadata calls, because the section name did not change.
 
== Handling Foreground and Background states ==
There are a few approaches to managing the Foreground and Background states of an app available to use for state measurement.
* Utilizing the Androidx LifeCycleObserver (The recommended approach starting sdk version 7.1.0.0+)
* Utilizing the [[DCR_Video_Android_SDK#The_SdkBgFgDetectionUtility_class|SdkBgFgDetectionUtility]] class
* Adding a tag to the Manifest XML
* Manual Management
=== The LifeCycleObserver ===
AndroidX replaces the original support library APIs with packages in the androidx namespace, and Android Studio 3.2 and higher provides an automated migration tool. (Select '''Refactor> Migrate to AndroidX''' from the menu bar.)
 
Starting with version 7.1.0, with AndroidX support, an additional utility is provided in the AppSDK - application background/foreground state detection by the AppSdk leveraging the Android Architecture component "LifeCycleObserver".
 
The AppSdk is now capable of detecting the application UI visibility state transitions between background and foreground, without forcing the applications to register for AppSdk's AppSdkApplication class, which is responsible for handling the detection of application background/foreground state transitions at present.
 
<blockquote>Please note, that if you already have an app designed that utilizes the depreciated SdkBgFgDetectionUtility Class, the AppSDK will ignore any calls to these methods if it can utilize the LifeCycleObserver.  LifeCycleObserver based auto detection will take precedence. </blockquote>
==== Adding the AndroidX dependency ====
In order to make use of the app background/foreground state transition auto detection feature of AndroidX AppSdk, the app gradle file needs the androidx dependency. The AppSdk API calls - <code>appInForeground()</code> and <code>appInBackground()</code>  will still be respected by AppSdk by executing the old AppSdk flow of handling "app in foreground" and "app in background" states as is.
 
==== Using the LifeCycle Extension ====
The following androidx dependency is required in the app gradle file:
<syntaxhighlight lang="java">
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
</syntaxhighlight>
 
<blockquote>
If you would like to take advantage of this auto detection feature of AppSdk at the very initial stage (e.g. splash screen or at of app launch time), before the AppSdk is initialized, can do so by calling the following newly introduced AppSdk public api, passing the application context :
<syntaxhighlight lang="java">
public static void registerLifeCycleObserver(Context applicationContext)
</syntaxhighlight>
</blockquote>
 
==== Log messages for the new auto detection ====
 
When the AppSdk app successfully registers for the LifeCycleObserver : <code>Registered LifeCycleObserver for App Background/Foreground auto-detection</code>
 
* When the app enters the foreground state :<code>App is in foreground, auto detected by AppSDK</code>
* When the app enters the background state :<code>App is in background, auto detected by AppSDK</code>
* If the client app doesn't have the "androidx" gradle dependency and AppSdk fails to register LifeCycleObserver :<code>AndroidX LifecycleObserver can not be observed. Please use androidx dependency to activate SDK auto-detection of app background/foreground state.</code>
* When the appInForeground() is explicitly called while LifeCycleObserver auto detection is active :<code>Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - foreground</code>
* When the appInBackground() is explicitly called while LifeCycleObserver auto detection is active :<code>Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - background</code>
 
=== The SdkBgFgDetectionUtility class ===
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement. It may be implemented in multiple ways for Android. This includes
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement. It may be implemented in multiple ways for Android. This includes
* Enable the Nielsen SDK to measure background/foreground state by makingthe relevant update to the AndroidManifest.
* Enable the Nielsen SDK to measure background/foreground state by makingthe relevant update to the AndroidManifest.
Line 63: Line 242:
* Custom implementation of the required methods within your application.
* Custom implementation of the required methods within your application.


=== ForeGround/Background Measurement via AndroidManifest ===
==== ForeGround/Background Measurement via AndroidManifest ====
The simplest way to measure the app background/foreground state is to add the following application tag to the Manifest XML. Integrating this into the Manifest XML will enable the SDK to measure app state directly. This approach is supported for Android 4.0 and up only; it requires that the application class is not in use for some other purpose.
The simplest way to measure the app background/foreground state is to add the following application tag to the Manifest XML. Integrating this into the Manifest XML will enable the SDK to measure app state directly. This approach is supported for Android 4.0 and up only; it requires that the application class is not in use for some other purpose.
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
<application android:name=”com.nielsen.app.sdk.AppSdkApplication”>
<application android:name="com.nielsen.app.sdk.AppSdkApplication">
</syntaxhighlight>
</syntaxhighlight>


=== Using the Android SdkBgFbDetectionUtility Class ===
==== Using the Android SdkBgFbDetectionUtility Class ====
For developers who are already using the application class, it is recommended that background/foreground state is implemented using the  [[Android_Background_Foreground|SdkBgFgDetectionUtility class]].  The  [[Android_Background_Foreground|SdkBgFgDetectionUtility class]] is compatible with Android 4+ and has been made available to Nielsen clients.
For developers who are already using the application class, it is recommended that background/foreground state is implemented using the  [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class].  The  [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class] is compatible with Android 4+ and has been made available to Nielsen clients. (You will need to copy/paste the code provided into a file).


=== Manual Background/ForeGround State Management ===
==== Manual Background/ForeGround State Management ====
In cases where the developer is not able to use the AndroidManifest.xml solution nor the Nielsen provided  [[Android_Background_Foreground|SdkBgFgDetectionUtility class]the developer will need to manually identify the change of state through the application and call the respective API (appInForeground() or appInBackground()) to inform the SDK regarding the change of state from background to foreground or foreground to background.
In cases where the developer is not able to use the AndroidManifest.xml solution nor the Nielsen provided  [https://engineeringportal.nielsen.com/docs/Android_Background_Foreground SdkBgFgDetectionUtility class] the developer will need to manually identify the change of state through the application and call the respective API (appInForeground() or appInBackground()) to inform the SDK regarding the change of state from background to foreground or foreground to background.


The SDK is informed about app state using the below methods.
The SDK is informed about app state using the below methods.
Line 85: Line 264:
Correct measurement of the foreground/background state is crucial to Static App measurement within Nielsen Digital Content Ratings (DCR).
Correct measurement of the foreground/background state is crucial to Static App measurement within Nielsen Digital Content Ratings (DCR).


== Nielsen Measurement Opt-Out Implementation ==
{{Template:Android_Privacy_and_Opt-Out}}
As a global information and measurement leader, we are committed to protecting the privacy and security of the data we collect, process and use. Our digital measurement products are not used to identify the consumer in any way, but they help us and our clients measure and analyze how consumers engage with media across online, mobile and emerging technologies, and offer insights into consumer behavior.
* When the app user wants to opt in or opt out of Nielsen measurement, a new dynamic page (with content string obtained from [[optOutURL]]) should be displayed.
* Use [[optOutStatus]] to retrieve the device’s Opt-Out status.
* This Opt-out page should be displayed in a webview (within the app) and not in any external browser.
* Capture the user’s selection in this page and pass it to the SDK through [[userOptOut]] for Nielsen to save the user’s preference.
* For more details, refer to [[Android SDK API Reference#Android Opt-Out Implementation|Android SDK API Reference - Android Opt-Out Implementation]] and Nielsen Digital Privacy.


== Pre-Certification Checklists ==
== Pre-Certification Checklists ==

Latest revision as of 21:06, 30 March 2023

Engineering Portal / Digital / US DCR & DTVR / DCR Static Android SDK

Overview

This guide covers DCR Static Only Implementation information for the Nielsen SDK. If implementation measurement for Video, please refer to our Video Guide.

Prerequisites

Before you start the integration, you will need:

Item Description Source
App ID (appid) Unique ID assigned to the player/site and configured by product. Provided by Nielsen
Nielsen SDK Includes SDK frameworks and sample implementation; See Android SDK Release Notes Download

If need App ID(s) or our SDKs, feel free to reach out to us and we will be happy to help you get started. Refer to Digital Measurement Onboarding guide for information on how to get a Nielsen App SDK and appid.

Implementation

This guide covers implementation steps for Android Studio utilizing the Nielsen SDK for DCR.

SDK Flavor Description
Android Ad Version * Opt-In and Opt-Out functionality managed by Opt out of Ads Personlization setting on device. (Preferred approach)
* The Nielsen SDK will collect the Google Advertising ID unless the user Opts Out.
* If the Google Play Service is unavailable, (ie: Amazon and Huawei devices) the Nielsen sdk will secure the Android ID.
* There are 3 versions available starting with the Nielsen SDK 8.1.0.0.
Android No Ad Framework * Without the Ad Framework, the Nielsen SDK cannot read the Google Advertising ID, so will retrieve the AndroidID.
* The AndroidID is a 64-bit number (expressed as a hexadecimal string), unique to each combination of app-signing key, user and device.
* The developer is required to present the User Choice Opt Out page which is described in the Privacy Section.
Android SDK noID * This version of the Nielsen SDK is perfect for Kid apps, or where no ID is required.
* Please review the Opt Out Requirement.

How to obtain the NielsenAppApi

The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of Gradle. We recommend using the Gradle-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.

SDK Initialization

The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated prior to version 5.1.1. (Version 4.0 for Android)

The following table contains the list of arguments that can be passed via the AppInfo JSON schema.

Parameter / Argument Description Source Required? Example
appid Unique Nielsen ID for the application. The ID is a GUID data type. If you did not receive your App ID, let us know and we will provide you. Nielsen-specified Yes PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
nol_devDebug Enables Nielsen console logging. Only required for testing Nielsen-specified Optional "DEBUG"

Debug flag for development environment

Player application developers / integrators can use Debug flag to check whether an App SDK API call made is successful. To activate the Debug flag, Pass the argument @"nol_devDebug":@"INFO", in the JSON string . The permitted values are:

  • INFO: Displays the API calls and the input data from the application (validate player name, app ID, etc.). It can be used as certification Aid.
  • WARN: Indicates potential integration / configuration errors or SDK issues.
  • ERROR: Indicates important integration errors or non-recoverable SDK issues.
  • DEBUG: Debug logs, used by the developers to debug more complex issues.

Once the flag is active, it logs each API call made and the data passed. The log created by this flag is minimal.

Note: DO NOT activate the Debug flag in a production environment.

Sample SDK Initialization Code

AppSDK() is no longer a singleton object and should be initialized as below.

Initialization of App SDK object through a JSON object

try
{
  // Prepare AppSdk configuration object (JSONObject)
  JSONObject appSdkConfig = new JSONObject()
          .put("appid", "PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA")
          .put("nol_devDebug", "DEBUG"); // only for debug builds

// Pass appSdkConfig to the AppSdk constructor
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);
}
catch (JSONException e)
{
  Log.e(TAG, "Couldn’t prepare JSONObject for appSdkConfig", e);
}

Here, appContext is the App context object and appSdkConfig is JSON object for holding the parameters (appid) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.


The integration of Nielsen App SDK will depend on type of client app.

  • Ensure that SDK files (AppSdk.jar and libAppSdk.so [App SDK 1.2 Only]) are included under the App’s project and the App SDK is linked to the App (the setting to link App SDK to the App can be found on property page of the App’s project).

Configure API calls - play

For static <App Measurement> content, play API is not required.

Configure API calls - loadMetadata

Use loadMetadata to pass 'content' Digital Measurement Metadata. The CMS data must be passed as a JSON object.

    loadMetadata(JSONObject jsonMetadata);

Refer to Digital Measurement Metadata for the list of parameters to be passed in the JSON object.

Note: The loadMetadata call must have ("type": "static").

Configure API calls - playheadPosition

For static <App Measurement> content, no playhead has to be supplied to the SDK.

stop

For static <App Measurement> content, stop API is not required.

API Call sequence

Call loadMetadata with JSON metadata as below.

    new JSONObject()
        .put("type", "static")
        .put("section", "siteSection")
        .put("assetid", "vid345-67483")
        .put("segA", "segmentA")
        .put("segB", "segmentB")
        .put("segC","segmentC")
    }

Sdk dataflow.jpg

Configure Metadata

Map the Nielsen keys to variables so that the content metadata is dynamically updated.

The Nielsen reserved keys are:

Key Description Data Type Value Required?
type asset type fixed 'static' Yes
assetid Unique ID for each article dynamic custom
(no Special Characters)
No
section section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values dynamic custom Yes
segA custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) dynamic custom No
segB custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) dynamic custom No
segC custom segment for reporting: Limit to 25 unique values across custom segments (segA + segB + segC) dynamic custom No

The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B & C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.

Aggregation Limits There are limits on the number of unique values that can be aggregated on in reporting. The specific limitations by key are:

Key Aggregation Limit
section maximum of 25 unique values (section <= 25)
segA Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)
segB Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)
segC Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)

DCR Static Duration Measurement per Section/Page/Asset

If your Nielsen AppID is enabled for DCR Static duration measurement, a view event will be recorded and a timer will be started for each screen/page. Duration will be measured until a new page is loaded or the app is moved to the background. The event which triggers recognition of page view and timer start is the loadMetadata API call with a metadata object of type 'static'. Once a page is viewed and the timer has started, duration will be measured until a new page has loaded with associated loadMetadata call having a different section name from the previous page. If a new loadMetadata call is made with the same section name, it will be ignored - no new view will be recorded. If it is desired to have a new view event even though the metadata contains the same section name (example: single-page apps having several assedIDs but common section name), staticEnd API can be called between page views.
Show flow diagram for above description

DCRstaticflow.png


Example 1 - In this example, a static view and duration ping with duration=25 will be generated for "SPORTS" section.
Show Android Java Example

JSONObject staticMetadataSports = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","SPORTS");
nielsenSDK.loadMetadata(staticMetadataSports);
        
      //in this example, after 25 seconds, new metadata is loaded for section "MOVIES"                   

JSONObject staticMetadataMovies = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","MOVIES");
nielsenSDK.loadMetadata(staticMetadataMovies);


Example 2 - In this example,, let's assume 20 seconds after the page is viewed, the app goes to background. A static duration ping with duration=20 will be generated for "SPORTS" section.
Show Android Java Example

JSONObject staticMetadataSports = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","SPORTS");
nielsenSDK.loadMetadata(staticMetadataSports);        
  
  //App goes to background or killed after 20 seconds.

Note: Once the app is returned to foreground or relaunched, the app needs to pass static metadata again in order to restart measuring DCR Static duration.

Example 3 - Here we wish to generate a new view event and start a new duration timer even though the section name in the metadata is the same.
Show Android Java Example

JSONObject staticMetadataSports = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","SPORTS");
staticMetadataSports.put("assetid","TENNIS");
nielsenSDK.loadMetadata(staticMetadataSports); 
//in this example, after 25 seconds, we pass staticEnd before new metadata is loaded for section "SPORTS", but assetid "CRICKET"


nielsenSDK.staticEnd();

JSONObject staticMetadataSports = new JSONObject();
staticMetadataSports.put("type","static");
staticMetadataSports.put("section","SPORTS");
staticMetadataSports.put("assetid","CRICKET");
nielsenSDK.loadMetadata(staticMetadataSports);

Note: Even though the assetid has changed, a new view event would not be recognized unless staticEnd() is called in between loadMetadata calls, because the section name did not change.

Handling Foreground and Background states

There are a few approaches to managing the Foreground and Background states of an app available to use for state measurement.

  • Utilizing the Androidx LifeCycleObserver (The recommended approach starting sdk version 7.1.0.0+)
  • Utilizing the SdkBgFgDetectionUtility class
  • Adding a tag to the Manifest XML
  • Manual Management

The LifeCycleObserver

AndroidX replaces the original support library APIs with packages in the androidx namespace, and Android Studio 3.2 and higher provides an automated migration tool. (Select Refactor> Migrate to AndroidX from the menu bar.)

Starting with version 7.1.0, with AndroidX support, an additional utility is provided in the AppSDK - application background/foreground state detection by the AppSdk leveraging the Android Architecture component "LifeCycleObserver".

The AppSdk is now capable of detecting the application UI visibility state transitions between background and foreground, without forcing the applications to register for AppSdk's AppSdkApplication class, which is responsible for handling the detection of application background/foreground state transitions at present.

Please note, that if you already have an app designed that utilizes the depreciated SdkBgFgDetectionUtility Class, the AppSDK will ignore any calls to these methods if it can utilize the LifeCycleObserver. LifeCycleObserver based auto detection will take precedence.

Adding the AndroidX dependency

In order to make use of the app background/foreground state transition auto detection feature of AndroidX AppSdk, the app gradle file needs the androidx dependency. The AppSdk API calls - appInForeground() and appInBackground() will still be respected by AppSdk by executing the old AppSdk flow of handling "app in foreground" and "app in background" states as is.

Using the LifeCycle Extension

The following androidx dependency is required in the app gradle file:

implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"

If you would like to take advantage of this auto detection feature of AppSdk at the very initial stage (e.g. splash screen or at of app launch time), before the AppSdk is initialized, can do so by calling the following newly introduced AppSdk public api, passing the application context :

public static void registerLifeCycleObserver(Context applicationContext)

Log messages for the new auto detection

When the AppSdk app successfully registers for the LifeCycleObserver : Registered LifeCycleObserver for App Background/Foreground auto-detection

  • When the app enters the foreground state :App is in foreground, auto detected by AppSDK
  • When the app enters the background state :App is in background, auto detected by AppSDK
  • If the client app doesn't have the "androidx" gradle dependency and AppSdk fails to register LifeCycleObserver :AndroidX LifecycleObserver can not be observed. Please use androidx dependency to activate SDK auto-detection of app background/foreground state.
  • When the appInForeground() is explicitly called while LifeCycleObserver auto detection is active :Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - foreground
  • When the appInBackground() is explicitly called while LifeCycleObserver auto detection is active :Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - background

The SdkBgFgDetectionUtility class

Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement. It may be implemented in multiple ways for Android. This includes

  • Enable the Nielsen SDK to measure background/foreground state by makingthe relevant update to the AndroidManifest.
  • Integrate Nielsen’s SdkBgFgDetectionUtility class within your Custom Application Class.
  • Custom implementation of the required methods within your application.

ForeGround/Background Measurement via AndroidManifest

The simplest way to measure the app background/foreground state is to add the following application tag to the Manifest XML. Integrating this into the Manifest XML will enable the SDK to measure app state directly. This approach is supported for Android 4.0 and up only; it requires that the application class is not in use for some other purpose.

<application android:name="com.nielsen.app.sdk.AppSdkApplication">

Using the Android SdkBgFbDetectionUtility Class

For developers who are already using the application class, it is recommended that background/foreground state is implemented using the SdkBgFgDetectionUtility class. The SdkBgFgDetectionUtility class is compatible with Android 4+ and has been made available to Nielsen clients. (You will need to copy/paste the code provided into a file).

Manual Background/ForeGround State Management

In cases where the developer is not able to use the AndroidManifest.xml solution nor the Nielsen provided SdkBgFgDetectionUtility class the developer will need to manually identify the change of state through the application and call the respective API (appInForeground() or appInBackground()) to inform the SDK regarding the change of state from background to foreground or foreground to background.

The SDK is informed about app state using the below methods.

AppLaunchMeasurementManager.appInForeground(getApplicationContext());
AppLaunchMeasurementManager.appInBackground(getApplicationContext());

Within the lifecycle of individual activities, onResume() and onPause() are best suited to providing indication of the app state.


Correct measurement of the foreground/background state is crucial to Static App measurement within Nielsen Digital Content Ratings (DCR).

Privacy and Opt-Out

There are currently 3 flavors of the Nielsen SDK:

  1. Global Android SDK Opt-out - managed by Opt out of Ads Personalization setting on device (preferred approach).
  2. Global Android SDK No Ad Framework Optout - Direct call to SDK. Can be used without Google Play Services or when using the noAd version of the SDK.
  3. Global Android SDK No ID Optout - Direct call to SDK. Should be used for Kids Category.

Global Android SDK Opt-out

OS-level Opt-out method available on Nielsen Android when the Google Play services APIs have been setup in your project.

The Nielsen SDK automatically leverages the Android's Opt out of Ads Personalization setting. The user is opted out of demographic measurement if the OS-level Opt out of Ads Personalization setting is enabled. As a publisher, you cannot override this setting.

Webview Element

It is a requirement to display a WebView element whose loadUrl is set to the value obtained from optOutURL. If using the Global Android SDK, this optOutURL informs the user how to deactivate/activate “Out of Ads Personalization”.

If you are implementing on Android TV or Fire TV here are your Opt Out verbiage options : https://engineeringportal.nielsen.com/docs/DCR_Video_%26_Static_CTV_Device_SDK_Privacy

Retrieve current Opt-Out preference

Whether the user is opted out via OS-level Opt-out or via App-level Opt-out, the current Opt-Out status as detected by the SDK is available via the getOptOutStatus() property in the Nielsen Android SDK API. appSdk.getOptOutStatus()

Global Android SDK No Ad Framework Optout

The No Ad Framework Optout can be used when the host application does not leverage Google Play Services such as when using the noAd version or the NoID version.

Nielsen Android SDK 5.1.1.18 and above will check for OS-level opt-out first, if available. The user will be opted out if indicated at the OS-level OR the App-level.

The No Ad Framework Optout method works as follows:

  • Get the current Nielsen opt-out URL via userOptOutURLString()
  • Display a WebView element whose loadUrl is set to the value obtained from userOptOutURLString()
  • Detect if the WebView URL changes to a special URL that indicates Opt-in, or Opt-out and close the WebView
    • Opt-out if the WebView URL = nielsenappsdk://1
    • Opt-in if the WebView URL = nielsenappsdk://0
  • Pass the detected URL to the userOptOut() function
    • Example:
      appSdk.userOptOut("nielsenappsdk://1");  // User opt-out
      

Global Android SDK No ID Optout (Kids_Category)

If you are building an app that will be listed in the Kids Category:

  1. Ensure that you are using the NoID version of the Nielsen SDK Framework.
  2. Immediately following the initialization of the Nielsen SDK ensure you call the userOptOut API with Opt out selection:
appSdk.userOptOut("nielsenappsdk://1");  // User opt-out

OptOut Example Code

Below you will find some sample code for the:

  • Global Android SDK - managed by Opt out of Ads Personalization setting on device (preferred approach).
  • Global Android noAd Framework - Use if Google Play APIs are unavailable or running noAd version.
  • It is currently not required to display an OptOut page for the NoID/Kids Build of the SDK.

Global OptOut Example

The below code is an AndroidX example of displaying the Nielsen Privacy page to the user. Please see the next section if using the No Ad Framework build

public class OptOutActivity extends AppCompatActivity implements IAppNotifier {

    WebView webView;
    AppSdk appSdk;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_optout);
        webView = (WebView) findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);

        webView.setWebViewClient(new WebViewClient() {
            @SuppressWarnings("deprecation")
            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Toast.makeText(OptOutActivity.this, description, Toast.LENGTH_SHORT).show();
            }
            @TargetApi(android.os.Build.VERSION_CODES.M)
            @Override
            public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
                // Redirect to deprecated method, so you can use it in all SDK versions
                onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());
            }

        });
        String url = appSdk.userOptOutURLString();   // Request Optout URL from NielsenSDK
        webView.loadUrl(url);                         //Display to the user in a Webview
    }
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        mSdkInterface.getSDK(appSdk);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (appSdk != null)
        {
            appSdk.close();
            appSdk = null;
        }
    }
}


No Ad Framework Optout Sample Code

The below code is an AndroidX example of displaying the Nielsen Privacy page to the user with the No Ad Framework SDK Build.

public class OptOutActivity extends AppCompatActivity implements IAppNotifier {

    WebView webView;
    AppSdk appSdk;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_optout);
        webView = (WebView) findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);

        webView.setWebViewClient(new WebViewClient() {
            @SuppressWarnings("deprecation")
            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Toast.makeText(OptOutActivity.this, description, Toast.LENGTH_SHORT).show();
            }
            @TargetApi(android.os.Build.VERSION_CODES.M)
            @Override
            public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
                // Redirect to deprecated method, so you can use it in all SDK versions
                onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());
            }

  
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                if(url.contains("nielsen")){
                    // If url value = "nielsenappsdk://1 it means the user selected Opt Out
                    // If url value = "nielsenappsdk://0" it means the user selected Opt-In
                    appSdk.userOptOut(url);
                }
                return true;
            }

        });
        String url = appSdk.userOptOutURLString();   // Request Optout URL from NielsenSDK
        webView.loadUrl(url);                         //Display to the user in a Webview
    }
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        mSdkInterface.getSDK(appSdk);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (appSdk != null)
        {
            appSdk.close();
            appSdk = null;
        }
    }
}

Retrieve current Opt-Out preference

Whether the user is opted out via OS-level Opt-out or via App-level Opt-out, the current Opt-Out status as detected by the SDK is available via the getOptOutStatus() property in the Nielsen Android SDK API. appSdk.getOptOutStatus()

Going Live

Following Nielsen testing, you will need to:

  1. Disable Debug Logging: Disable logging by deleting {nol_devDebug: 'DEBUG'} from initialization call.
  2. Notify Nielsen: Once you are ready to go live, let us know so we can enable you for reporting. We will not be able to collect or report data prior to receiving notification from you.

Pre-Certification Checklists

After the application is ready to be sent for Nielsen Certification, please go through the Pre-Certification Checklist and ensure the app behaves as expected, before submitting to Nielsen.

Testing an Implementation - App

See Digital Measurement Testing.