Android SDK API Reference: Difference between revisions

From Engineering Client Portal

 
(21 intermediate revisions by 5 users not shown)
Line 12: Line 12:
* The Java AppSdk.jar library that runs on the Android’s Dalvik Virtual Machine.
* The Java AppSdk.jar library that runs on the Android’s Dalvik Virtual Machine.
* The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.
* The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.
<blockquote>'''Note''': App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.</blockquote
<blockquote>'''Note''': App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.</blockquote>


The requirement for the Java ''AppSdk.jar'' library and the ''libAppSdk.so'' native library will depend on the type of host application that will make use of them.
The requirement for the Java ''AppSdk.jar'' library and the ''libAppSdk.so'' native library will depend on the type of host application that will make use of them.
Line 22: Line 22:


=== Setting up in Eclipse IDE ===
=== Setting up in Eclipse IDE ===
Ensure to unzip the Nielsen App SDK sample app and copy the ''AppSdk.jar'' into the libs/ folder on the App’s Eclipse project. Copy the ''libAppSdk.so'' file under ''libs/armeabi/'' folder into the same Eclipse project.
Be sure to unzip the Nielsen App SDK sample app and copy the ''AppSdk.jar'' into the libs/ folder on the App’s Eclipse project. Copy the ''libAppSdk.so'' file under ''libs/armeabi/'' folder into the same Eclipse project.
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective ''libAppSdk.so'' can be found under the ''libs/x86/'', ''libs/mips/'', and ''libs/armeabi-7a/'' folders.
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective ''libAppSdk.so'' can be found under the ''libs/x86/'', ''libs/mips/'', and ''libs/armeabi-7a/'' folders.
Add the following permissions on the project’s ''AndroidManifest.xml'' file.
Add the following permissions on the project’s ''AndroidManifest.xml'' file.
Line 28: Line 28:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/></syntaxhighlight>
<uses-permission android:name="android.permission.INTERNET"/></syntaxhighlight>
For more details to handle runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].  Download the latest ''google-play-services_lib'' and include it in the App’s project in order to use the App SDK.
For more details to handle run-time permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].  Download the latest ''google-play-services_lib'' and include it in the App’s project in order to use the App SDK.
 
* App SDK checks to see if there is a Google service available and updated.
* App SDK checks to see if there is a Google service available and updated.
* If not available or updated, App SDK will not use this service when executing its functions and will make reference to missing imports and the app will not be compiled.
* If not available or updated, App SDK will not use this service when executing its functions and will make reference to missing imports and the app will not be compiled.
Line 79: Line 80:


For more information, refer to https://developer.android.com/google/play-services/setup.html
For more information, refer to https://developer.android.com/google/play-services/setup.html
*For applications using ''Google Play Services 17.0.0'' and above, one of the following tags must be included within ''AndroidManifest.xml'', or the application will crash (more information https://developers.google.com/ad-manager/mobile-ads-sdk/android/quick-start#update_your_androidmanifestxml]):
**<syntaxhighlight lang="java">com.google.android.gms.ads.APPLICATION_ID</syntaxhighlight>
**<syntaxhighlight lang="java">com.google.android.gms.ads.AD_MANAGER_APP</syntaxhighlight>


== Initialization ==
== Initialization ==
Line 89: Line 94:
[[AppSDK()]] is no longer a singleton object and should be initialized as below.
[[AppSDK()]] is no longer a singleton object and should be initialized as below.


'''Initialization of App SDK object through a JSON object'''
==== APPSDK Kotlin/Java Interpretability ====
<syntaxhighlight lang="objective-c">
 
JSONObject config = null;
Starting Nielsen SDK version 9.0.0.0, all new feature/modules are written in Kotlin language, coexisting with legacy features written in Java. If you are having an app purely written in Java language, then you need to enable the Kotlin support dependency in your project as described below:
 
try
Minimum version of kotlin plugin and org.jetbrains.kotlin:kotlin-stdlib dependency supported by AppSDK is 1.4.0.  <br/>
{
To enable kotlin support in your java based android project please add below gradle dependency in your app's build.gradle file
  // Prepare AppSdk configuration object (JSONObject)
<syntaxhighlight lang="gradle">
  JSONObject appSdkConfig = new JSONObject()
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.0"
          .put("appid", "TXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
          .put("appname", "Sample App Name")
          .put("sfcode", "uat-cert")
          .put("nol_devDebug", "INFO") // only for debug builds
          .put("custom_key1", "custom_value1")
          .put("custom_key2", "custom_value2");
// 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>
</syntaxhighlight>
<br/><br/>


Here, <code>appContext</code> is the App context object and <code>appSdkConfig</code> is JSON object for holding the parameters (<code>appid</code>, <code>appname</code>, <code>sfcode</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.
{{Initialization_of_App_SDK_object_through_a_JSON_object}}


==== Android Application Life Cycle with respect to Nielsen App SDK ====
==== Android Application Life Cycle with respect to Nielsen App SDK ====
Line 127: Line 120:
*Call [[stop()]] when ending or pausing a viewing session.
*Call [[stop()]] when ending or pausing a viewing session.
*During session playback, call the SDK [[setPlayheadPosition()]] and / or [[sendID3()]]
*During session playback, call the SDK [[setPlayheadPosition()]] and / or [[sendID3()]]
**Call [[setPlayheadPosition()]] every one second until the stream is stopped or paused. Normally this happens on Digital Audio measurements.
**Call [[setPlayheadPosition()]] every one second until the stream is stopped or paused.
**Call [[sendID3()]] if the client relies on the Nielsen ID3 tags for its measurements; this call should happen whenever a new Nielsen ID3 metadata is available for processing. Normally this happens on DTVR and ID3 measurements.
**Call [[sendID3()]] if the client relies on the Nielsen ID3 tags for its measurements; this call should happen whenever a new Nielsen ID3 metadata is available for processing. Normally this happens on DTVR and ID3 measurements.
Nielsen App SDK object handles filtering of ID3 tags and CMS tags, queuing/buffering of data, and all communications with Nielsen collection facility.
Nielsen App SDK object handles filtering of ID3 tags and CMS tags, queuing/buffering of data, and all communications with Nielsen collection facility.
*The client’s app must clearly identify the mode of operation (live vs. VOD) and stick to the type of playhead coordinates until the playback is completed. The client must reliably provide the appropriated playhead position value depending on the type of content streamed.
*The client’s app must clearly identify the mode of operation (live vs. VOD) and stick to the type of playhead coordinates until the playback is completed. The client must reliably provide the appropriated playhead position value depending on the type of content streamed.
*If streaming live video content, the client must pass the current UTC time in seconds as playhead position.
*If streaming live video content, the client must pass the current Unix timestamp (seconds since Jan-1-1970 UTC) as playhead position.
*If streaming VOD (video on demand), the client must stream the offset from the beginning of the file as playhead position.
*If streaming VOD (video on demand), the client must stream the offset from the beginning of the file as playhead position.
*For all Digital Audio listening, the client must pass the current UTC time in seconds as playhead position, regardless of station type.


== Retrieving ID3 Tags ==
== Retrieving ID3 Tags ==
Line 153: Line 145:
| Google ExoPlayer || Android 4.1 ||
| Google ExoPlayer || Android 4.1 ||
|-
|-
| Brightcove Player || Android 4.1 || Support for Android versions 2.3.3 and 4.0 is now deprecated. Learn more about why Brightcove is removing support for these versions as of January 1, 2016 in this [https://support.brightcove.com/en/perform/docs/announcement-brightcove-sdk-android-version-support|announcement]
| Adobe PrimeTime Player || Android 4.2 ||
|-
|-
| Adobe PrimeTime Player || Android 4.2 ||
| Brightcove Player || Android 4.1 || Support for Android versions 2.3.3 and 4.0 is now deprecated. Learn more about why Brightcove is removing support for these versions as of January 1, 2016 in this announcement: https://support.brightcove.com/en/perform/docs/announcement-brightcove-sdk-android-version-support
|-
|-
| VisualOn Player || Android 2.3 || Android 5 is the latest supported version
| VisualOn Player || Android 2.3 || Android 5 is the latest supported version
Line 161: Line 153:
| NexStream Player || Android 1.6 || Supported till Android 6
| NexStream Player || Android 1.6 || Supported till Android 6
|}
|}


==== Android Native Media Player ====
==== Android Native Media Player ====
Line 330: Line 321:
{| class="wikitable sortable"
{| class="wikitable sortable"
|-
|-
! Scenario !! Method / Property !! DTVR !! DAR !! Digital Audio !! DCR !! International (Germany) !! Description
! Scenario !! Method / Property !! DTVR !! DAR !! DCR !! International (Germany) !! Description
|-
|-
| Initialize || [[AppSDK()]] || ✔ || ✔ || ✔ || ✔ || ✔ || Used to create a new instance of the SDK object
| Initialize || [[AppSDK()]] || ✔ || ✔ || ✔ || ✔ || Used to create a new instance of the SDK object
|-
|-
| Measurement || [[play()]] || ✔ || ✔ || ✔ || ✔ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. If this is not called then the “channel name” value populated will be the default value of “defaultChannelName”.
| Measurement || [[play()]] || ✔ || ✔ || ✔ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. If this is not called then the “channel name” value populated will be the default value of “defaultChannelName”.
|-
|-
| Measurement || [[loadMetadata()]] || ✔ || ✔ || ✔ || ✔ || ✔ || Used when there is a preroll ad that needs to be associated with content metadata. The loadmetadata will first be called to populate the content metadata values and then the loadMetadata for ad metadata will be called. This allows sending a content ping with the ad info, even if the user bails out during the preroll ad.
| Measurement || [[loadMetadata()]] || ✔ || ✔ || ✔ || ✔ || Used when there is a preroll ad that needs to be associated with content metadata. The loadmetadata will first be called to populate the content metadata values and then the loadMetadata for ad metadata will be called. This allows sending a content ping with the ad info, even if the user bails out during the preroll ad.
|-
|-
| Measurement || [[sendID3()]] || ✔ || ✘ || ✘ || ✘ || ✘ || Used to send the ID3 metadata.
| Measurement || [[sendID3()]] || ✔ || ✘ || ✘ || ✘ || Used to send the ID3 metadata.
|-
|-
| Measurement || [[setPlayheadPosition()]] || ✘ || ✘ || ✔ || ✔ || ✔ || Used to send the playhead position.
| Measurement || [[setPlayheadPosition()]] || ✘ || ✘ || ✔ || ✔ || Used to send the playhead position.
|-
|-
| Measurement || [[stop()]] || ✔ || ✘ || ✔ || ✔ || ✔ || Used when playback is paused and when switching between ad and content or content and ad.
| Measurement || [[stop()]] || ✔ || ✘ || ✔ || ✔ || Used when playback is paused and when switching between ad and content or content and ad.
|-
|-
| Measurement || [[end()]] || ✔ || ✘ || ✔ || ✔ || ✔ || Used when content playback is complete. This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content
| Measurement || [[end()]] || ✔ || ✘ || ✔ || ✔ || Used when content playback is complete. This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content
|-
|-
| Measurement || [[updateOTT()]] || || || ✘ || ✘ || ✔ || Used to notify App SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).
| Measurement || [[staticEnd()]] ||   ||   || || ✔ || Used with DCR Static duration in between loadMetadata calls for static content when section name is the same but a new static view event and duration measurement restart is desired
|-
|-
| Opt-out || [[userOptOutURLString()]] || || ✔ || ✔ || || ✔ || Used to fetch the Nielsen opt-out web page URL.
| Measurement || [[updateOTT()]] || || || || ✔ || Used to notify App SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).
|-
|-
| Opt-out || [[userOptOut()]] || ✔ || ✔ || ✔ || ✔ || ✔ || Used to supply the response message from opt-out webpage to the SDK.
| Opt-out || [[userOptOutURLString()]] || ✔ || ✔ || ✔ || ✔ || Used to fetch the Nielsen opt-out web page URL.
|-
|-
| Opt-out || [[getOptOutStatus()]] || || ✘ || ✘ || ✘ || ✔ || Call this API to retrieve the Opt-Out or Opt-In state.
| Opt-out || [[userOptOut()]] || ✔ || ✔ || ✔ || ✔ || Used to supply the response message from opt-out webpage to the SDK.
|-
| Opt-out || [[getOptOutStatus()]] || ✘ || ✘ || ✘ || ✔ || Call this API to retrieve the Opt-Out or Opt-In state.
|-
|-
| Opt-out
| Opt-out
| [[appDisableApi()]]
| [[appDisableApi()]]
(kill switch)  
(kill switch)  
|| ✔ || ✔ || ✔ || ✔ || ✔ || Used to disable the SDK.
|| ✔ || ✔ || ✔ || ✔ || Used to disable the SDK.
|-
| Opt-out || [[getAppDisable()]] || ✔ || ✔ || ✔ || ✔ || Used to query if the SDK is disabled or not.
|-
|-
| Opt-out || [[getAppDisable()]] || ✔ || ✔ || ✔ || ✔ || ✔ || Used to query if the SDK is disabled or not.
| Log || [[getLastEvent()]] || ✔ || ✔ || ✔ || ✔ || Used to query the SDK for the last status
|-
|-
| Log || [[getLastEvent()]] || ✔ || ✔ || ✔ || ✔ || ✔ || Used to query the SDK for the last status
| Log || [[getLastError()]] || ✔ || ✔ || ✔ || ✔ || Used to query the SDK for the last error
|-
|-
| Log || [[getLastError()]] || ✔ || ✔ || ✔ || ✔ || ✔ || Used to query the SDK for the last error
| Log || [[isValid()]] || ✔ || ✔ || ✔ || ✔ || Used to check if the SDK was successfully instantiated or not.
|-
|-
| Log || [[isValid()]] || ✔ || ✔ || || || ✔ || Used to check if the SDK was successfully instantiated or not.
| Log || [[getMeterVersion()]] || || || || ✔ || Returns the current SDK version.
|-
|-
| Log || [[getMeterVersion()]] || || || ✘ || ✘ || ✔ || Returns the current SDK version.
| Log || [[getNielsenId()]] || || || || ✔ || Used to get a string defining the Nielsen ID (NUID) number for the device.
|-
|-
| Log || [[getNielsenId()]] || ✔ || ✔ || ✔ || ✔ || ✔ || Used to get a string defining the Nielsen ID (NUID) number for the device.
| Log || [[getDeviceId()]] || ✔ || ✔ || ✔ || ✔ || Returns the current device id.
|-
|-
| Log || [[getDeviceId()]] || || ✔ || ✔ || ✔ || ✔ || Returns the current device id.
| Log || [[appInBackground()]] || || || ✔ || ✔ || Used to capture the event of app going to background.
|-
|-
| Log || [[appInBackground()]] || ✘ || ✘ || ✘ || ✔ || ✔ || Used to capture the event of app going to background.
| Log || [[appInForeground()]] || ✘ || ✘ || ✔ || ✔ || Used to capture the event of app coming to foreground
|-
|-
| Log || [[appInForeground()]] || ✘ || ✘ || ✘ || ✔ || ✔ || Used to capture the event of app coming to foreground
| Log || [[setDebug()]] || ✘ || ✘ || ✘ || ✔ || Used to enable/disable debug flags. Newly introduced in SDK version 5.0.0 for International (Germany)
|-
|-
| Log || [[setDebug()]] || || || ✘ || ✘ || ✔ || Used to enable/disable debug flags. Newly introduced in SDK version 5.0.0 for International (Germany)
| Viewability<br/>Audibility
| [[trackViewability()]]
|| ||   || || ✔ || Used to start the viewability measurement.
|}
|}


Line 421: Line 418:


== Opt-out Android SDK Version '''5.1.1.18 or above''' ==
== Opt-out Android SDK Version '''5.1.1.18 or above''' ==
<blockquote>'''Note:''' If using Android SDK Versions 1.2.3, 4.0.0.8, 5.1.0, 5.1.1.14, skip ahead to: [[#Opt-out Android SDK Version 1.2.3, 4.0.0.8, 5.1.0, 5.1.1.14|Opt-out Android SDK Version 1.2.3, 4.0.0.8, 5.1.0, 5.1.1.14]]</blockquote>
<blockquote>'''Note:''' If using legacy Android SDK Versions 5.1.1.14 or below, or are not using Google Play Services, skip ahead to: [[#Opt-out for legacy SDK versions prior to 5.1.1.18 or if host application does not leverage Google Play Services|Opt-out for legacy SDK versions prior to 5.1.1.18 or if host application does not leverage Google Play Services]]</blockquote>


Starting from SDK version 5.1.1.18, Opt-Out related behavior has been changed in the following ways:
Starting from SDK version 5.1.1.18, Opt-Out related behavior has been changed in the following ways:
Line 433: Line 430:
<blockquote>'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.</blockquote>
<blockquote>'''Note:''' For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.</blockquote>


== Opt-out Android SDK Version '''1.2.3, 4.0.0.8, 5.1.0, 5.1.1.14''' ==
== Opt-out for legacy SDK versions prior to 5.1.1.18 or if host application does not leverage Google Play Services ==
<blockquote>'''Note:''' If using Android SDK Version 5.1.1.18 or above, refer to documentation above ([[#Opt-out Android SDK Version 5.1.1.18 or above|Opt-out Android SDK Version 5.1.1.18 or above]])</blockquote>
<blockquote>'''Note:''' If using Android SDK Version 5.1.1.18 or above, refer to documentation above ([[#Opt-out Android SDK Version 5.1.1.18 or above|Opt-out Android SDK Version 5.1.1.18 or above]])</blockquote>


Line 447: Line 444:
private class MonitorWebView extends WebViewClient
private class MonitorWebView extends WebViewClient
{
{
   private static final String NIELSEN_URL_OPT_OUT = “nielsenappsdk://1”;
   private static final String NIELSEN_URL_OPT_OUT = "nielsenappsdk://1";
   private static final String NIELSEN_URL_OPT_IN = “nielsenappsdk://0”;
   private static final String NIELSEN_URL_OPT_IN = "nielsenappsdk://0";
   
   
   @Override
   @Override
Line 491: Line 488:


== Nielsen Sample Applications ==
== Nielsen Sample Applications ==
<br/><br/>
=== Viewability testing ===
The sample applications shipped with client package have support for viewability metrics verification. The player view can be moved using a finger-dragging gesture or scrolling in the application window. This allows the tester to reduce the visible area of the player view and check the resulting data. Additional UI buttons:
*Cover View button opens a popup with multiple UI controls which allow changing a player view alpha and visibility as well as showing a cover view in front of the player view.
*Alert button allows for opening a native UI alert in the application.
[[File:PlayerView Zoomin.png|200px]]&nbsp;&nbsp;&nbsp;&nbsp;[[File:PlayerView AlertView.png|200px]]&nbsp;&nbsp;&nbsp;&nbsp;[[File:PlayerView Dragging.png|200px]]&nbsp;&nbsp;&nbsp;&nbsp;[[File:PlayerView FriendlyViews.png|200px]]


== Nielsen Privacy Requirements ==
== Nielsen Privacy Requirements ==
Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.
Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.
*Disclosure of viewership data collection in app store description
*Disclosure of viewership data collection in EULA / Privacy Policy
*Disclosure of viewership data collection in EULA / Privacy Policy
*A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used
*A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used
Line 595: Line 597:
* If the user has this app running on more than one mobile device, the user will need to opt out of this measurement on each device.
* If the user has this app running on more than one mobile device, the user will need to opt out of this measurement on each device.
<blockquote>'''Note''': Opt Out feature does NOT rely on "Opt Out of Ads for Personalization" setting since Nielsen’s systems provide measurement metrics and do not serve ads to users.</blockquote>
<blockquote>'''Note''': Opt Out feature does NOT rely on "Opt Out of Ads for Personalization" setting since Nielsen’s systems provide measurement metrics and do not serve ads to users.</blockquote>
In the Description of the app in Google Play Store, include a short description about Nielsen measurement, as below.
<blockquote>'''Sample Google Play Store Disclosure'''
This app features Nielsen proprietary measurement software which will allow you to contribute to market research, like Nielsen’s TV Ratings.
To learn more about our digital measurement products and your choices in regard to them, please visit http://www.nielsen.com/digitalprivacy for more information.</blockquote>


== Event and Error Handling ==
== Event and Error Handling ==
Line 621: Line 616:
{| class="wikitable"
{| class="wikitable"
|-
|-
! Event Code !! Event Name !! Description !! Behavior
! Error Code !! Error Name !! Description !! Behavior
|-
|-
| 1001 || ERROR_FAILED_CREATE_URL_STRING || Failed generating ping string due to error on parsing || Include last error message from URL parser
| 1001 || ERROR_FAILED_CREATE_URL_STRING || Failed generating ping string due to error on parsing || Include last error message from URL parser
Line 667: Line 662:
| 1022 || ERROR_FAILED_PROCESS_STOP || App SDK failed processing stop ||
| 1022 || ERROR_FAILED_PROCESS_STOP || App SDK failed processing stop ||
|}
|}
== Viewability and Audibility Implementation ==
Viewability metrics will allow AppSDK to track the visibility of the player and collect information about how much the player container is visible to the end user while playback is occurring.
The viewability pings will be fired following the same rules as for measurement pings. These pings will be POST requests, not GET requests like other data pings. POST body for viewability requests will contain the key-value pairs in JSON format. The key parameters in the URL schemes are '''invs, inau, inss, invp''' and '''ines''' which will contain the collected viewability data. This data will be formatted according to the specific rules so that downstream it will be possible to match measurement and viewability data for a session.
Audibility metrics will capture the volume level as well as mute/unmute state of the device while playback is occurring.
=== Data Collected ===
{| class="wikitable"
|-
! Parameter !! Description
|-
| Measured Value || Value is different for different request parameters:
{| class="wikitable"
|-
| '''invs''' ||  Intersection ratio for the target view in percent (from 0 to 100). Default threshold for this value is 5. Example: ['''50''',1,1528457356,10]
|-
| '''inau''' || Volume level on the device in percent (from 0 to 100), where 0 - mute, 100 - max volume level. Default threshold for this value is 1. Example: ['''30''',1,1528457356,10]
|-
| '''inss''' || Device screen size as "WxH", where W - is width in pixels, H - is height in pixels. Example: ['''"1024x768"''',1,1528457356,10]
|-
| '''invp''' || Current window size. It is different than the device screen size in a multiple scene mode or on a desktop. Format is "WxH", where W - is width in pixels, H - is height in pixels. Example: ['''"800x600"''',1,1528457356,10]
|-
| '''ines''' || Player view size as "WxH", where W - is width in pixels, H - is height in pixels. Example: ['''"300x200"''',1,1528457356,10]
|}
|-
| Start offset || Value contains the first playhead or the first id3 offset with non-null CID after start, flush or resume. Example playhead: [50,'''1''',1528457356,10]. Example id3 offset: [50,'''70100''',1528457356,10]
|-
| Start timestamp || Timestamp value when the time period related to this time series item was started. Example: [50,1,'''1528457356''',10]
|-
| Duration || Duration value is calculated as a difference between the last playhead and the first playhead for the current time series item. Example: [50,1,1528457356,'''10''']
|}
Viewability support requires additional parameters to be provided from player applications to the SDK. In order to provide these parameters and to start the viewability measurement the following method has been added to the public SDK API (please refer to the [[trackViewability()|trackViewability public API reference]] for the details and usage examples):
<br/><br/>
<syntaxhighlight lang="java">
void  trackViewability(JSONObject);
</syntaxhighlight>
<br/>
For Audibility measurement APPSDK uses android system API in order to get an volume level for the device:
<syntaxhighlight lang="java">
AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
float currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int volumeLevel = (int) ((currentVolume/maxVolume) * 100);
</syntaxhighlight>

Latest revision as of 19:44, 10 May 2023

Engineering Portal / Digital / Android SDK API Reference
The Nielsen App SDK (located in the com.nielsen.app.sdk package) class is the primary application interface to the Nielsen App SDK on Android.

  • Create and initialize an instance object of AppSdk class.
  • The player application can use this object to collect HLS timed metadata through a sendID3() call.

The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package. It inherits from the closeable interface and exposes the public APIs the client’s app will use. Below is the declaration of the AppSdk class: public class AppSdk implements Closeable

Setting Up Development Environment

Nielsen App SDK is compatible with Android OS versions 2.3+. Clients can control / configure the protocol to be used – HTTPS or HTTP to suit their needs.

The Nielsen App SDK 1.2 library is composed of two parts:

  • The Java AppSdk.jar library that runs on the Android’s Dalvik Virtual Machine.
  • The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.

Note: App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.

The requirement for the Java AppSdk.jar library and the libAppSdk.so native library will depend on the type of host application that will make use of them.

  • For Video player applications
    • The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 3.0 and later will support it natively).
    • If the player application uses a 3rd party media player implementing its own HLS, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.
  • For Audio player applications
    • The Android OS hosting the App SDK should be at version 2.3 and later since the SDK depends on the Google Play support to work properly.

Setting up in Eclipse IDE

Be sure to unzip the Nielsen App SDK sample app and copy the AppSdk.jar into the libs/ folder on the App’s Eclipse project. Copy the libAppSdk.so file under libs/armeabi/ folder into the same Eclipse project.

  • App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective libAppSdk.so can be found under the libs/x86/, libs/mips/, and libs/armeabi-7a/ folders.

Add the following permissions on the project’s AndroidManifest.xml file.

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:required="false" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

For more details to handle run-time permissions in Android versions, please visit [1]. Download the latest google-play-services_lib and include it in the App’s project in order to use the App SDK.

  • App SDK checks to see if there is a Google service available and updated.
  • If not available or updated, App SDK will not use this service when executing its functions and will make reference to missing imports and the app will not be compiled.

To include the Google Play library in the media player project, copy the google-play-services_lib folder into the same location as the project

  • Access File > Import.
  • Select Existing Android Code into Workspace and click Next.
  • Click Browse and navigate to the google-play-services_lib to include it into the projects.
  • Select the exact Project Build Target for Eclipse to use from Android SDK.
    • Android 4.4.2, etc. OR
    • Edit project.properties file to point to Android target version e.g. target= android-19.

andr-properties-drm.jpg

Once the google-play-services_lib is included into the App project, include the following code under the <application> node in the AndroidManifest.xml.

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>

Also, include the version.xml file that comes with the google-play-services_lib under the res/values directory of the media player project.

  • Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.

Nielsen App SDK uses the following packages/classes from the Google Play service.

Library:

  • google-play-services_lib

Classes/package:

  • com.google.android.gms.ads.identifier.AdvertisingIdClient;
  • com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
  • com.google.android.gms.common.ConnectionResult;
  • com.google.android.gms.common.GooglePlayServicesUtil;
  • com.google.android.gms.common.GooglePlayServicesRepairableException;
  • com.google.android.gms.common.GooglePlayServicesNotAvailableException;

Setting up in Android Studio IDE

Launch Android Studio and select Import project (Eclipse ADT).

andr-setup-launch.jpg

Browse for project destination directory and click Next.

andr-import-project.jpg

Go to File > Project Structure > App > Dependencies.

andr-pro-structure.jpg

Click + to add library dependency.

Select play-services and click OK

andr-choose-library.jpg

For more information, refer to https://developer.android.com/google/play-services/setup.html

Initialization

Android Application Life Cycle with respect to Nielsen App SDK

andr-init-img1.jpg

Step 1: App SDK initialization

For API version 4.0.0 and above

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

APPSDK Kotlin/Java Interpretability

Starting Nielsen SDK version 9.0.0.0, all new feature/modules are written in Kotlin language, coexisting with legacy features written in Java. If you are having an app purely written in Java language, then you need to enable the Kotlin support dependency in your project as described below:

Minimum version of kotlin plugin and org.jetbrains.kotlin:kotlin-stdlib dependency supported by AppSDK is 1.4.0.
To enable kotlin support in your java based android project please add below gradle dependency in your app's build.gradle file

implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.0"



Initialization of App SDK object through a JSON object

JSONObject config = null;
 
try
{
  // Prepare AppSdk configuration object (JSONObject)
  JSONObject appSdkConfig = new JSONObject()
          .put("appid", "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
          .put("sfcode", "dcr")
          .put("nol_devDebug", "INFO") // only for debug builds
          .put("custom_key1", "custom_value1")
          .put("custom_key2", "custom_value2")
          .put("uid2", "MTKVpUAzwYAPnHrtfE0wlINOMzhU7UUEjjVdCdRu63k=")
          .put("uid2_token", "AgAAAAPFR0zA5ogv/yaAPiUsAdZPsfqS8QlDSGxAB+rr8yekFs3AjLYVk5qqqiyV2XHbSuwzHmxSlLeQeKQI1mp015jsNnpX5/xGgXldcgVz+gFnyh3T8/3agMwRmyrhCxG4oH2C7fc48AQk2eotE7FW0ZDEYM8fD9ZxDaxFUC/OV3OuZA==")
          .put("hem_sha256", "e46f3f2c8c0e1d509aeb04d2fd78f0481c8520cb6769c258a50ddb98b073dabc")
          .put("hem_sha1", "")
          .put("hem_md5", "");
// 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, sfcode) 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.

Android Application Life Cycle with respect to Nielsen App SDK

andr-radioandvideo-app.jpg

Step 2: App SDK libraries inclusion in project

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).

Step 3: Nielsen App SDK Streaming Sessions

After ensuring that the SDK object has been initialized, link the streaming session APIs. The next steps are:

  • Call play() when starting or resuming a streaming session. Use the channelName parameter to pass channel descriptor information. The channel name field is a 32-character free-form text field containing the name of the program or feed being sent (such as ESPN2, Food Network, etc.) which must be inserted on a JSON string.
  • Load the CMS metadata by calling the loadMetadata() on the SDK object.
  • Call stop() when ending or pausing a viewing session.
  • During session playback, call the SDK setPlayheadPosition() and / or sendID3()
    • Call setPlayheadPosition() every one second until the stream is stopped or paused.
    • Call sendID3() if the client relies on the Nielsen ID3 tags for its measurements; this call should happen whenever a new Nielsen ID3 metadata is available for processing. Normally this happens on DTVR and ID3 measurements.

Nielsen App SDK object handles filtering of ID3 tags and CMS tags, queuing/buffering of data, and all communications with Nielsen collection facility.

  • The client’s app must clearly identify the mode of operation (live vs. VOD) and stick to the type of playhead coordinates until the playback is completed. The client must reliably provide the appropriated playhead position value depending on the type of content streamed.
  • If streaming live video content, the client must pass the current Unix timestamp (seconds since Jan-1-1970 UTC) as playhead position.
  • If streaming VOD (video on demand), the client must stream the offset from the beginning of the file as playhead position.

Retrieving ID3 Tags

ID3 tags have a payload of about 249 characters and start with "www.nielsen.com".

Sample ID3 tags

  • www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/X100zdCIGeIlgZnkYj6UvQ==/AAAB2Jz2_k74GXSzx4npHuI_JwJd3QSUpW30rDkGTcbHEzIMWleCzM-uvNOP9fzJcQMWQLJqzXMCAxParOb5sGijSV9dNM3QiBniJYGZ5GI-lL1fXTTN0IgZ4iWBmeRiPpS9AAAAAAAAAAAAAAAAAAAAAFJWFM5SVhTONNU=/00000/00000/00
  • www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/R8WHe7pEBeqBhu8jTeXydg==/AAICoyitYqlxT7n6aZ0oMCGheFi4CXFp46AMUPZz1lMr_M9tr3_cjee1SHqxrOiVerMDLeyn9xzocZSKwi746Re8vNOtpNCAZjYABs_J0R25IHpvOc1HS8QHGgD5TgOJeS6gX100zdCIGeIlgZnkYj6UvVJWFNhSVhTiPE0=/00000/46016/00

Note: ID3 tags are not applicable for International (Germany)

Extracting ID3 tags from Android Players

ID3 Support Matrix

Player Name Minimum supported version Description
Android Native Media Player Android 6 Android 6 Media Player allows apps to register a callback to be invoked, when a selected track has the timed metadata available. Currently, only HTTP Live Streaming (HLS) data URI’s embedded with timed ID3 tags, generates TimedMetaData.
Google ExoPlayer Android 4.1
Adobe PrimeTime Player Android 4.2
Brightcove Player Android 4.1 Support for Android versions 2.3.3 and 4.0 is now deprecated. Learn more about why Brightcove is removing support for these versions as of January 1, 2016 in this announcement: https://support.brightcove.com/en/perform/docs/announcement-brightcove-sdk-android-version-support
VisualOn Player Android 2.3 Android 5 is the latest supported version
NexStream Player Android 1.6 Supported till Android 6

Android Native Media Player

As the Android Media Player versions (prior to Android 6 / Android API 23) do not support ID3, Nielsen has created a library that becomes an extension to the media player, thus MPX. This library extracts the ID3 tags and sends them to the app. For more information on how to use the MPX component, refer to the Nielsen-supplied sample application.

Starting from Android 6 (Android API 23), Android Native Media Player allows apps to register a callback to be invoked, when a selected track has the timed metadata available. Currently, only HTTP Live Streaming (HLS) data URI’s embedded with timed ID3 tags generate TimedMetadata. Once the HLS video starts, call onTimedMetaDataAvailable() as and when the player observes a TimedMetadata (ID3 tag).

@Override
   public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data)
     {
       byte[] iD3PayloadArray = data.getMetaData();
       String iD3Payload = new String(iD3PayloadArray, StandardCharsets.UTF_8);
       if (null != iD3Payload && iD3Payload.contains("www.nielsen.com"))
         {
           int index = iD3Payload.indexOf("www.nielsen.com");
           String id3String = iD3Payload.substring(index, (index + 249));
           Log.d(TAG, "TimedMetaData ID3 Tag:" + id3String);
           appProcessID3tag(id3String);
         }
     }

ExoPlayer

he SDK is designed around an event-driven architecture where components emit events to allow other components to listen and respond to state changes.

Player SDK Classes used:

com.google.android.exoplayer.demo.player.DemoPlayer

Since Nielsen App SDK is interested in extracting the Timed Metadata (ID3 Tags) in HLS and VOD on the EXO Player, trace the ID3_TAG emitted during video content played using EXOPlayer component as below.

DemoPlayer implements ExoPlayer.Listener
—————————————————–
/**
* A listener for receiving ID3 metadata parsed from the media stream.
*/
public interface Id3MetadataListener
{
  void onId3Metadata(Map<String, Object> metadata);
}
——————————————————-
MetadataTrackRenderer.MetadataRenderer<Map<String,
Object>> getId3MetadataRenderer()
  {
    return new MetadataTrackRenderer.MetadataRenderer<Map<String, Object>>()
      {
        @Override
        public void onMetadata(Map<String, Object> metadata)
          {
            if (id3MetadataListener != null)
              {
                id3MetadataListener.onId3Metadata(metadata);
              }
          }
      };
  }

Also in Player.java class:

Player implements DemoPlayer.Id3MetadataListener
—————————————————–
@SuppressWarnings("rawtypes")
@Override
public void onId3Metadata(Map<String, Object> metadata)
{
  try
    {
      for (Object o : metadata.entrySet())
        {
          Map.Entry pairs = (Map.Entry) o;
          if (metadata.containsKey(TxxxMetadata.TYPE))
            {
              TxxxMetadata txxxMetadata = (TxxxMetadata) metadata
              .get(TxxxMetadata.TYPE);
            }
          else
            {
              String aStr = new String((byte[]) pairs.getValue());
              MainActivity.mAppSdk.sendID3(aStr);
            }
        }
    }
  catch (Exception e)
    {
      e.printStackTrace();
      Log.d(TAG, "onId3Metadata(): No Id3 tags");
    }
}

andr-exo-retrievingID3tags.png

Brightcove Player

While the Brightcove player plays the content, EventListener triggers an event when an ID3 packet is received (SeamlessVideoDisplayComponent.ID3_TAG). Upon receiving this event, collect the incoming ID3 tags and only pass the Nielsen payload of the PRIV frame to the App SDK for analysis.

brightcoveVideoView.getEventEmitter().on(SeamlessVideoDisplayComponent.ID3_TAG, new EventListener()
  {
    public void processEvent(Event event)
      {
        NlsId3Tag nlsID3 = new NlsId3Tag(event.properties.get(SeamlessVideoDisplayComponent.ID3_DATA).toString());
        Log.w("ID3", nlsID3.NlsPayload);
        // Sent ID3 Tags to App
        appProcessID3tag(nlsID3.NlsPayload);
      }
      });
  }

Adobe PrimeTime Player

While the Adobe PrimeTime player plays the content, MediaPlayer.PlaybackEventListener triggers a callback when an ID3 packet is received (onTimedMetadata). Upon receiving this event, collect the incoming ID3 tags and only pass the Nielsen payload of the PRIV frame to the App SDK for analysis.

public void onTimedMetadata(TimedMetadata id3Metadata)
{
  NlsId3Tag nlsID3 = new NlsId3Tag(id3Metadata.getMetadata().toString());
  Log.w(LOG_TAG, "ID3 Timed Data –> " + nlsID3.NlsPayload);
  Log.w(LOG_TAG, "PayLoad Size –> " + nlsID3.NlsPayload.length());
  appProcessID3tag(nlsID3.NlsPayload);
}

VisualOn Player

While the VisualOn player plays the content, VOCommonPlayerListener triggers an event when an ID3 packet is received (VO_OSMP_SRC_CUSTOMERTAGID_TIMEDTAG). Upon receiving this event, collect the incoming ID3 tags and only pass the Nielsen payload of the PRIV frame to the App SDK for analysis.

case VO_OSMP_SRC_CB_CUSTOMER_TAG:
{
  VO_OSMP_SRC_CUSTOMERTAGID tag = VO_OSMP_SRC_CUSTOMERTAGID.valueOf(nParam1);
  switch (tag)
    {
      case VO_OSMP_SRC_CUSTOMERTAGID_TIMEDTAG:
      // do something with this tag
      int time = nParam2;
      byte[] b = (byte[]) obj;
      String s = new String(b);
      NlsId3Tag nlsID3 = new NlsId3Tag(b);
      // Sent ID3 Tags to App
      appProcessID3tag(nlsID3.NlsPayload);
      if (appid3If != null)
      appid3If.onId3(nlsID3.NlsPayload);
      break;
      case VO_OSMP_SRC_CUSTOMERTAGID_MAX:
      // ignore this type of tag
      break;
      default:
      break;
    }
      break;
}

NextStream Player

ID3 tags will be received in the NexStream Player through onTimedMetaRenderRender(NexPlayer mp,NexID3TagInformation metadata) callback API. A sample implementation for the callback is shown below:

public void onTimedMetaRenderRender(NexPlayer mp, NexID3TagInformation m)
  {
    text = m.getPrivateFrame();
    if (text != null)
      {
        data = text.getTextData();
        if (data != null)
          {
            // make sure to identify the beginning  of  the
            // Nielsen ID3 tag payload by searching for the
            // "www.nielsen.com" string on the ID3 tag and
            // passing to the App SDK all information that
            // follows. It should be:
            // nlsPayload = "www.nielsen.com" + dataFollowing
            nlsPayload = getDataAfterWwwNielsenCom(data);
            if (nlsPayload!= NULL)
            mAppSdk.sendID3(nlsPayload);
          }
      }
  }

The sendID3() sends the extracted Nielsen ID3 payload to the App SDK for analysis.

Android SDK API Methods & Properties

Scenario Method / Property DTVR DAR DCR International (Germany) Description
Initialize AppSDK() Used to create a new instance of the SDK object
Measurement play() Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. If this is not called then the “channel name” value populated will be the default value of “defaultChannelName”.
Measurement loadMetadata() Used when there is a preroll ad that needs to be associated with content metadata. The loadmetadata will first be called to populate the content metadata values and then the loadMetadata for ad metadata will be called. This allows sending a content ping with the ad info, even if the user bails out during the preroll ad.
Measurement sendID3() Used to send the ID3 metadata.
Measurement setPlayheadPosition() Used to send the playhead position.
Measurement stop() Used when playback is paused and when switching between ad and content or content and ad.
Measurement end() Used when content playback is complete. This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content
Measurement staticEnd() Used with DCR Static duration in between loadMetadata calls for static content when section name is the same but a new static view event and duration measurement restart is desired
Measurement updateOTT() Used to notify App SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).
Opt-out userOptOutURLString() Used to fetch the Nielsen opt-out web page URL.
Opt-out userOptOut() Used to supply the response message from opt-out webpage to the SDK.
Opt-out getOptOutStatus() Call this API to retrieve the Opt-Out or Opt-In state.
Opt-out appDisableApi()

(kill switch)

Used to disable the SDK.
Opt-out getAppDisable() Used to query if the SDK is disabled or not.
Log getLastEvent() Used to query the SDK for the last status
Log getLastError() Used to query the SDK for the last error
Log isValid() Used to check if the SDK was successfully instantiated or not.
Log getMeterVersion() Returns the current SDK version.
Log getNielsenId() Used to get a string defining the Nielsen ID (NUID) number for the device.
Log getDeviceId() Returns the current device id.
Log appInBackground() Used to capture the event of app going to background.
Log appInForeground() Used to capture the event of app coming to foreground
Log setDebug() Used to enable/disable debug flags. Newly introduced in SDK version 5.0.0 for International (Germany)
Viewability
Audibility
trackViewability() Used to start the viewability measurement.

Android Opt-Out Implementation

To opt out, users must have access to "About Nielsen Measurement" page. User can click this page from app settings screen.

Include About Nielsen Measurement and Your Choices link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.

  • URL to this web page should be called from SDK by invoking userOptOutURLString() and opened in 'WebView' / External browser.
  • If the App SDK returns NULL as Opt-Out URL, handle the exception gracefully and retry later.
  • To retrieve the current Opt-Out status of a device, use the getOptOutStatus() method.

Displaying Opt-Out in a WebView

optOutUrl = mAppSdk.userOptOutURLString();
if(optOutUrl !=null)
{
   mWebView = (WebView) findViewById(R.id.webView);
   mWebView.getSettings().setJavaScriptEnabled(true);
   mWebView.getSettings().setBuiltInZoomControls(true);
   mWebView.getSettings().setDisplayZoomControls(false);
   mWebView.getSettings().setLoadWithOverviewMode(true);
   mWebView.getSettings().setUseWideViewPort(true);
   mWebView.setWebViewClient(new MonitorWebView());
   mWebView.setWebChromeClient(new WebChromeClient());
   mWebView.loadUrl(optOutUrl);
}
else
{
   //Handle it gracefully and Retry later
}

The app must provide access to "About Nielsen Measurement" page for the users. Include "About Nielsen Measurement" and Your Choices link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.

Privacy policy iOS.jpg

Note: When ‘WebView’ / External browser is closed, do not pass the status returned from ‘WebView’ / External browser to the SDK within the app, as the new Opt-Out page will not return any response.

Note: App SDK manages the user’s choice (Opt-Out / Opt-In), the app does not need to manage this status.

Sequence Diagram

optoutsequence-andr.jpg

Opt-out Android SDK Version 5.1.1.18 or above

Note: If using legacy Android SDK Versions 5.1.1.14 or below, or are not using Google Play Services, skip ahead to: Opt-out for legacy SDK versions prior to 5.1.1.18 or if host application does not leverage Google Play Services

Starting from SDK version 5.1.1.18, Opt-Out related behavior has been changed in the following ways:

  • SDK will be sending the data pings to census even though SDK is opted out (In earlier releases all the traffic from SDK to census will be ceased). However, all the outgoing pings will have the parameter uoo=true using which backend can ignore this data.
  • Current Opt-Out page is now updated to have no hyperlinks for Opt-Out / Opt-In operations. SDK Opt-Out has to be done via

Google Settings → Ads → Opt out of Ads Personalization.

Note: For Amazon devices, see Opt-Out Implementation for Amazon Devices below.

andr-ads.jpg

Note: For API Version 5.1 and above, App SDK will fire data pings and continue measurement even after the user has opted out from Nielsen measurement on a device. The data ping will be marked as opted-out ping.

Opt-out for legacy SDK versions prior to 5.1.1.18 or if host application does not leverage Google Play Services

Note: If using Android SDK Version 5.1.1.18 or above, refer to documentation above (Opt-out Android SDK Version 5.1.1.18 or above)

When a user clicks the Opt-Out / Opt-In link, the application should invoke optOutURL to get the link to the Nielsen Privacy page from SDK.

Privacy Page

privacy-policy.jpg

  • There are two click here links – one for Opt-Out and one for Opt-In. Click the required link:
    • Capture user’s selection
    • Pass the selection back to the SDK via the userOptOut().

Capture and forward user selection

private class MonitorWebView extends WebViewClient
{
  private static final String NIELSEN_URL_OPT_OUT = "nielsenappsdk://1";
  private static final String NIELSEN_URL_OPT_IN = "nielsenappsdk://0";
 
  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url)
  {
    if (NIELSEN_URL_OPT_OUT.equals(url)
      || NIELSEN_URL_OPT_IN.equals(url))
    {
      // Get AppSdk instance from the host
      AppSdk appSdk = HostApp.getAppSdk();
      // Send the URL to the AppSdk instance
      appSdk.userOptOut(url);
      return true;
    }
    return false;
  }
}

Note: When 'WebView' is closed, pass the status returned from 'WebView' to the SDK within the app.

Note: App SDK manages the user's choice (Opt-Out / Opt-In), the app does not need to manage this status.

Opt-Out Implementation for Amazon Devices

Amazon device users can opt out or opt back into Nielsen Measurement, any time using the device’s setting – 'Limit Ad Tracking' (Interest-based ads).

User is opted out of Nielsen Online Measurement when ‘Limit Ad Tracking’ is enabled.


For devices running on Fire OS 5.1 and above, retrieve the Ad tracking value.

Retrieving Ad tracking Value

ContentResolver cr = getContentResolver();
int limitAdTracking = Secure.getInt(cr, "limit_ad_tracking", 2);
  • Returns limit_ad_tracking value "0" if enabled
  • Returns limit_ad_tracking value "1" if disabled
  • Returns limit_ad_tracking value "2" if ad tracking is not supported (below Fire OS 5.1).

Note: Google Play Services are not needed to retrieve ad tracking state on Amazon devices. Limit Ad Tracking can be accessed through Settings → Apps & Games → Advertising ID.

Nielsen Sample Applications



Viewability testing

The sample applications shipped with client package have support for viewability metrics verification. The player view can be moved using a finger-dragging gesture or scrolling in the application window. This allows the tester to reduce the visible area of the player view and check the resulting data. Additional UI buttons:

  • Cover View button opens a popup with multiple UI controls which allow changing a player view alpha and visibility as well as showing a cover view in front of the player view.
  • Alert button allows for opening a native UI alert in the application.

PlayerView Zoomin.png    PlayerView AlertView.png    PlayerView Dragging.png    PlayerView FriendlyViews.png

Nielsen Privacy Requirements

Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.

  • Disclosure of viewership data collection in EULA / Privacy Policy
  • A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used
  • Method for users to opt-out of Nielsen measurement, any time while using the application

Ratings Data Flow

Every view of creditable and watermarked content is measured by Nielsen. RatingsDataFlow.png

Information NOT Shared

  • With Nielsen
    • User's Identity
  • With Data Provider
    • Content information
    • Whether user is viewing an ad or video content
    • Player used to play the streaming (audio / video, etc.)
    • Values being de-duped / aggregating for

Nielsen collects only what it needs for audience measurement. Every view of creditable, watermarked content will be measured by Nielsen.

Data Collected

Type of Information Parameter Transmitted to Nielsen? Sent to Provider?
Nielsen ID3 Watermark
FinalDistributor Timestamp Yes No
Program Content Timestamp Yes No
Mobile Breakout Code Yes No
Commercial Credit Code – Linear or Dynamic Yes No
Time ShiftedViewing Code Yes No
Segment Number Yes No
Segment View Pattern Yes No
Device/App Info
Device OSVersion Yes Yes
Device Model Yes No
Device Advertiser ID (Apple IDFA or Google AdID/Android ID) Yes Yes
Cache Buster Yes Yes
App Version Yes No
App Name Yes No
SDKDisabled Flag Yes No
ServerCode Yes No
Channel or URL Yes No
Nielsen Identifiers
Client ID Yes No
Campaign ID Yes Yes
Nielsen Unique Device ID Yes No
Application ID Yes No
DeviceGroup (ex. Tablet, Smartphone, Desktop) Yes Yes
OS Group (ex. Android, iOS, Windows) Yes Yes
SDKVersion Yes No
IP Address for DMA, Country Code Yes Yes

Note: Data is hashed, and encrypted using AES 128 before transmission to data provider.

Example ping sent to provider

  • https://provider.com/cgi-bin/brandlift.php?campaign_id=ff12725d724fac7934cf6003f096b4cd&placement_id=a4164b8fba9ee7c873a9c72c7091bb58&creative_id=25280139b61a947e127a52f56c8a2fdd&segment1=9000&segment2=41&segment3=iOS&OSVer=iOS6.1&c9=&devgrp=tablet&h=f5f243fe6d&rnd=1376971827360


This ping passes the following parameters to the provider:

  • Campaign ID – (campaign, placement, creative)
  • Country Code
  • DMA
  • OS Group (ex. iOS, Android)
  • DeviceOS Version
  • Device Advertiser ID
  • DeviceGroup (ex. Tablet, Smartphone, Desktop)
  • Cache Buster

Nielsen Measurement Opt-Out

In accordance with Nielsen’s SDK licensing agreement, developers are required to provide basic informational data to users about Nielsen’s Privacy Policy with a navigation to additional information on Nielsen measurement.

Nielsen currently uses Opt Out of Ads for Personalization for the latest versions of the SDK (5.1.1.18 and above). However, for older SDK versions, the app must provide a means for the user to opt out, or opt back in to Nielsen Measurement. Users can opt out of Nielsen online measurement research through this feature.

  • If the user has this app running on more than one mobile device, the user will need to opt out of this measurement on each device.

Note: Opt Out feature does NOT rely on "Opt Out of Ads for Personalization" setting since Nielsen’s systems provide measurement metrics and do not serve ads to users.

Event and Error Handling

App SDK Event Codes

Event Code Event Name Event Description
2000 EVENT_INITIATE App SDK is initiated. It will happen as soon as the App SDK is initialized
2001 EVENT_STARTUP App SDK has started up. It will happen only after App SDK has received a valid config file. This is the location in the code to acquire the value of userOptOutURLString().
2002 EVENT_SHUTDOWN App SDK is shutting down. It will happen just before App SDK is destroyed

App SDK Error Codes

Constants with predefined error codes which the AppSdk object can generate.

Error Code Error Name Description Behavior
1001 ERROR_FAILED_CREATE_URL_STRING Failed generating ping string due to error on parsing Include last error message from URL parser
1002 ERROR_FAILED_RECEIVE_CONFIG Failed to receive configuration file from Census On 5th time, it will log event and keep requesting config 10 min apart
1003 ERROR_FAILED_PARSING_CONFIG Failed parsing the config file JSON string Include json error number/short message from iOS or Android
1004 ERROR_FAILED_PARSING_PLAY Failed parsing the play() JSON string Include JSON error number/short message from iOS or Android
1005 ERROR_FAILED_PARSING_METADATA Failed parsing the play() JSON string Include JSON error number/short message from iOS or Android
1006 ERROR_FAILED_GENERATING_PING Failed creating ping before adding it to the UPLOAD table) Include ping nol_url index, cadence to identify ping
1007 ERROR_FAILED_PROCESSOR_START Failed starting data processor thread. Normally, that means a product Include processor that failed to start
1008 ERROR_FAILED_PROCESS_ID3 Failed processing data on a data processor. Normally, that means the input to a product Include processor and data that failed to process (ID3 tag on a MTVR impression, for example)
1009 ERROR_FAILED_HTTP_SEND Failed sending HTTP or HTTPS requests Include HTTP error number
1010 ERROR_FAILED_SENDING_PING Failed sending pings (on ANDROID, the ping on the UPLOAD table) Include ping up to 80 char from the end
1011 ERROR_FAILED_SENDING_TSV Failed sending TSV requests Include TSV request message
1012 ERROR_FAILED_SENDING_STATION_ID Failed sending Station ID requests Include Station ID request message
1013 ERROR_FAILED_ACCESSING_DB Failed read/write from/to database table Include SQL statement and data and SQLite error number/message
1014 ERROR_CHANGED_DEVICE_ID Device ID changed
1015 ERROR_CHANGED_NUID NUID changed
1016 ERROR_SDK_NOT_INITIALIZED App SDK initialization failed
1017 ERROR_FAILED_SDK_SUSPEND App SDK failed to suspend activities
1018 ERROR_INVALID_PARAMETERS App SDK invalid parameters
1019 ERROR_INVALID_STATE App SDK called in incorrect state
1020 ERROR_FAILED_PROCESS_PLAYHEAD App SDK failed processing playhead position
1021 ERROR_FAILED_PROCESS_METADATA App SDK failed processing not-null, syntax valid JSON metadada
1022 ERROR_FAILED_PROCESS_STOP App SDK failed processing stop

Viewability and Audibility Implementation

Viewability metrics will allow AppSDK to track the visibility of the player and collect information about how much the player container is visible to the end user while playback is occurring.

The viewability pings will be fired following the same rules as for measurement pings. These pings will be POST requests, not GET requests like other data pings. POST body for viewability requests will contain the key-value pairs in JSON format. The key parameters in the URL schemes are invs, inau, inss, invp and ines which will contain the collected viewability data. This data will be formatted according to the specific rules so that downstream it will be possible to match measurement and viewability data for a session.

Audibility metrics will capture the volume level as well as mute/unmute state of the device while playback is occurring.

Data Collected

Parameter Description
Measured Value Value is different for different request parameters:
invs Intersection ratio for the target view in percent (from 0 to 100). Default threshold for this value is 5. Example: [50,1,1528457356,10]
inau Volume level on the device in percent (from 0 to 100), where 0 - mute, 100 - max volume level. Default threshold for this value is 1. Example: [30,1,1528457356,10]
inss Device screen size as "WxH", where W - is width in pixels, H - is height in pixels. Example: ["1024x768",1,1528457356,10]
invp Current window size. It is different than the device screen size in a multiple scene mode or on a desktop. Format is "WxH", where W - is width in pixels, H - is height in pixels. Example: ["800x600",1,1528457356,10]
ines Player view size as "WxH", where W - is width in pixels, H - is height in pixels. Example: ["300x200",1,1528457356,10]
Start offset Value contains the first playhead or the first id3 offset with non-null CID after start, flush or resume. Example playhead: [50,1,1528457356,10]. Example id3 offset: [50,70100,1528457356,10]
Start timestamp Timestamp value when the time period related to this time series item was started. Example: [50,1,1528457356,10]
Duration Duration value is calculated as a difference between the last playhead and the first playhead for the current time series item. Example: [50,1,1528457356,10]

Viewability support requires additional parameters to be provided from player applications to the SDK. In order to provide these parameters and to start the viewability measurement the following method has been added to the public SDK API (please refer to the trackViewability public API reference for the details and usage examples):

void  trackViewability(JSONObject);


For Audibility measurement APPSDK uses android system API in order to get an volume level for the device:

AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
float currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int volumeLevel = (int) ((currentVolume/maxVolume) * 100);