Android Basic example
From Engineering Client Portal
Android Studio Example
The code below shows a sample implementation of the Nielsen SDK. The goal of this project was to design a very basic application using the built in AVPlayer. The SDK packages do come with a variety of additional Sample Applications that we encourage each developer to review in addition to the below code. If you have any questions, please reach out to your Account Manager or Technical Account Manager.
NielsenInit.java
public class NielsenInit {
private AppSdk mAppSdk = null;
public AppSdk initAppSdk(Context mContext, IAppNotifier appNotifier){
try {
//Initialising the NielsenAppSDK class by passing app information which returns the instance of AppSdk.
JSONObject appInformation = new JSONObject()
.put("appid", "PDA7D5EE6-B1B8-4123-9277-2A788BXXXXXX")
.put("appversion", "1.0")
.put("sfcode", "dcr")
.put("nol_devDebug", "INFO");
mAppSdk = new AppSdk(mContext, appInformation, appNotifier);
} catch (JSONException e) {
e.printStackTrace();
}
return mAppSdk;
}
}
SDKMethods.java
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created on 02/03/18.
*/
public class SDKMethods {
public String url = "";
JSONObject content = null;
public void setContentUrl(){
//Loading Content URL
url = "http://www.nielseninternet.com/NielsenConsumer/prog_index.m3u8";
}
public void setAdUrl(){
//Loading Ad URL
url = "http://www.nielseninternet.com/NWCC-3002/prog_index.m3u8";
}
public void setDtvrUrl(){
//Loading DTVR URL
url = "http://www.nielseninternet.com/VOD/NielsenScienceBehindWhatsNext/prog_index.m3u8";
}
//Loading Channel Info.
public JSONObject loadChannelInfo(){
JSONObject channel = null;
try {
channel = new JSONObject()
.put("channelName", "ChannelTitle")
.put("mediaURL", url);
} catch (JSONException e) {
e.printStackTrace();
}
return channel;
}
//Loading content Data
public JSONObject loadContentData(){
url = "http://www.nielseninternet.com/NielsenConsumer/prog_index.m3u8";
JSONObject content = null;
try {
content = new JSONObject()
.put( "type","content")
.put( "assetid","C77664")
.put( "length","3600")
.put( "program","MyProgram")
.put( "segB","CustomSegmentValueB")
.put( "segC","segmentC")
.put( "title","S2,E3")
.put( "section","cloudApi_app")
.put( "airdate","20180306 10:00:00")
.put( "isfullepisode","y")
.put( "adloadtype","2")
.put( "channelName","My Channel 1")
.put( "pipMode","false");
} catch (JSONException e) {
e.printStackTrace();
}
return content;
}
//Loading PreRoll Ad data
public JSONObject loadPreRollAdData(){
url = "http://www.nielseninternet.com/NWCC-3002/prog_index.m3u8";
JSONObject ad = null;
try {
//We should pass content dictionary also in Ad video.
ad = new JSONObject()
.put("type", "preroll")
.put("assetid", "AD1")
.put("title", "ADPreTitle");
} catch (JSONException e) {
e.printStackTrace();
}
return ad;
}
//Loading DTVR data
public JSONObject loadDtvr() {
JSONObject dtvr = null;
url = "http://www.nielseninternet.com/NWCC-3002/prog_index.m3u8";
try {
dtvr = new JSONObject()
.put( "type","content")
.put("adModel", "1");
} catch (JSONException e) {
e.printStackTrace();
}
return dtvr;
}
}
MainActivity.java
package com.nielsen.simple_playerstandard_android_sdk_7000.activities;
import ...
public class MainActivity extends AppCompatActivity implements IAppNotifier, SurfaceHolder.Callback, View.OnClickListener,
MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener,
MediaPlayer.OnTimedMetaDataAvailableListener, MediaPlayer.OnInfoListener {
public static final String TAG = MainActivity.class.getSimpleName();
private SurfaceView mSurfaceView;
private SeekBar seek;
Button btnPlay;
TextView txtMetadata;
AppSdk appSdk;
private int videoType, totalVideos;
private int totalVideosPlayed = 0;
private boolean isVideoStarted = true, isPaused = false;
JSONObject data = null;
private MediaPlayer mMediaPlayer;
private SurfaceHolder mSurfaceHolder;
SDKMethods sdkMethods;
private ProgressDialog dialog;
private Handler playheadHandler;
private Runnable playheadRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Mark: In SDKMethods class we wrote methods which creates content,Ad,DTVR objects,urls
sdkMethods = new SDKMethods();
initUI();
getIntents();
//Mark: In NielsenInit class we are initialising the NielsenSDK.
//Getting the instance of NielsenSDK.
NielsenInit nielsenInit = new NielsenInit();
//3rd parameter "this" referes to IAppNotifier interface which is needed to initialise NielsenSDK.
appSdk = nielsenInit.initAppSdk(getApplicationContext(), this);
mSurfaceView = findViewById(R.id.surface_view);
mSurfaceView.setVisibility(View.VISIBLE);
showProgressDialog();
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(MainActivity.this);
}
private void initUI() {
//Initialising UI elements
seek = findViewById(R.id.seek);
btnPlay = findViewById(R.id.btnPlay);
txtMetadata = (TextView) findViewById(R.id.txtMetadata);
btnPlay.setOnClickListener(this);
}
private void getIntents() {
//Getting intents from previous activity
videoType = getIntent().getIntExtra(Constants.INTENT_VIDEO_TYPE, 0);
totalVideos = getIntent().getIntExtra(Constants.INTENT_TOTAL_VIDEOS, 0);
if(videoType == Constants.onlyContent){
//loading video content url
sdkMethods.setContentUrl();
txtMetadata.setText(sdkMethods.loadContentData().toString());
}else if(videoType == Constants.dtvrVideo){
//loading video DTVR url
sdkMethods.setDtvrUrl();
txtMetadata.setText(sdkMethods.loadDtvr().toString());
}else{
//loading video Ad url
sdkMethods.setAdUrl();
txtMetadata.setText(sdkMethods.loadPreRollAdData().toString());
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.v(TAG, "surfaceCreated Called");
if (isPaused) {
//Once video is resumed after pause, setting surfaceholder to player.
if (mMediaPlayer != null) {
mSurfaceHolder = mSurfaceView.getHolder();
mMediaPlayer.setDisplay(mSurfaceHolder);
}
} else {
//This will execute only for first time.
setUpPlayer();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnErrorListener(this);
}
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
try {
playheadHandler.removeCallbacks(playheadRunnable);
///As video completed playing, incrementing the variable value.
totalVideosPlayed++;
if (videoType == Constants.onlyContent || totalVideosPlayed == totalVideos) {
//When content video completes or total videos finishes, call "end" method.
appSdk.end();
} else {
//On completion of "AD" call "stop" method.
appSdk.stop();
}
releaseMediaPlayer();
checkVideosToBePlayed();
} catch (Exception e) {
e.printStackTrace();
}
}
//Checks if any videos are pending to play.
private void checkVideosToBePlayed(){
//Checking if total videos played or not.
if (totalVideosPlayed != totalVideos) {
data = new JSONObject();
//Checking if videoType is contentWithOneAd, then after completion of Ad, will play the content video.
if (videoType == Constants.contentWithOneAd) {
//loading video content data
data = sdkMethods.loadContentData();
txtMetadata.setText(sdkMethods.loadContentData().toString());
}
showProgressDialog();
setUpPlayer();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnErrorListener(this);
}
}
@Override
public boolean onError(MediaPlayer mediaPlayer, int i, int li) {
Log.e(TAG, "Player error codes:" + i + ", " + li);
return false;
}
//creating player
private void setUpPlayer() {
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setDataSource(sdkMethods.url);
mMediaPlayer.setOnPreparedListener(MainActivity.this);
mMediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.v(TAG, "surfaceChanged Called");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.v(TAG, "surfaceDestroyed Called");
}
@Override
public void onPrepared(MediaPlayer mp) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if(totalVideosPlayed == 0){
//Only for first time sending Channel info to SDK using "play" method.
appSdk.play(sdkMethods.loadChannelInfo());
}
if(videoType == Constants.dtvrVideo){
//loading DTVR metadata
data = sdkMethods.loadDtvr();
}else{
//loading video content metadata data
data = sdkMethods.loadContentData();
}
//Sending metadata to SDK.
appSdk.loadMetadata(data);
if(videoType == Constants.contentWithOneAd && totalVideosPlayed == 0){
//loading Ad data before playing ad
data = sdkMethods.loadPreRollAdData();
//Sending Ad metadata to SDK.
appSdk.loadMetadata(data);
}
if(videoType == Constants.dtvrVideo){
//Setting infoListener and TimedMetaDataListener to listen ID3 tags, needed only for DTVR
mMediaPlayer.setOnInfoListener(this);
mMediaPlayer.setOnTimedMetaDataAvailableListener(this);
}
//Setting max value to seekbar
seek.setMax(convertTotime(mMediaPlayer.getDuration()));
isVideoStarted = true;
updateSeekbarAndPlayhead();
mMediaPlayer.start();
}
@Override
protected void onPause() {
super.onPause();
setPauseAction();
}
private void setPauseAction() {
try {
if (mMediaPlayer != null) {
isVideoStarted = false;
isPaused = true;
//Pausing media player
mMediaPlayer.pause();
//As video is paused calling "stop" method of SDK.
appSdk.stop();
btnPlay.setText(getString(R.string.play));
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseMediaPlayer();
}
private void releaseMediaPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnPlay:
playPauseMedia();
break;
}
}
private void playPauseMedia(){
try {
//If video is not yet played, then it will "play" else it will "pause" the video
if (!isVideoStarted) {
btnPlay.setText(getString(R.string.pause));
if (isPaused) {
isVideoStarted = true;
isPaused = false;
mMediaPlayer.start();
} else {
/*
mSurfaceView = findViewById(R.id.surface_view);
mSurfaceView.setVisibility(View.VISIBLE);
*/
showProgressDialog();
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(MainActivity.this);
}
} else {
//Pause button clicked, so pausing the video
setPauseAction();
}
} catch (Exception e) {
e.printStackTrace();
}
}
//Updates seekbar
private void updateSeekbarAndPlayhead() {
try {
playheadHandler = new Handler();
//Make sure you update Seekbar on UI thread
MainActivity.this.runOnUiThread(playheadRunnable = new Runnable() {
@Override
public void run() {
if (mMediaPlayer != null) {
//getting current position of media player
int mCurrentPosition = mMediaPlayer.getCurrentPosition() / 1000;
seek.setProgress(mCurrentPosition);
try {
//Checking If video player is not paused and video is playing and is not a DTVR video
if (!isPaused && mMediaPlayer.isPlaying() && videoType != Constants.dtvrVideo) {
//Sending playHeadPosition to SDK. (Not needed for DTVR video)
appSdk.setPlayheadPosition(mCurrentPosition);
}
} catch (Exception e) {
e.printStackTrace();
}
}
playheadHandler.postDelayed(this, 1000);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private int convertTotime(long milliSec) {
return (int) (milliSec / 1000);
}
private void showProgressDialog() {
runOnUiThread(new Runnable() {
public void run() {
//Showing progress dialog
dialog = new ProgressDialog(MainActivity.this);
dialog.setCancelable(false);
dialog.setMessage(getString(R.string.loading));
dialog.show();
}
});
}
@Override
public void onAppSdkEvent(long l, int i, String s) {
//Default method of IAppNotifier interface
}
//Needed only for DTVR video
@Override
public void onTimedMetaDataAvailable(MediaPlayer mediaPlayer, TimedMetaData timedMetaData) {
if(timedMetaData != null && timedMetaData.getMetaData() != null && mMediaPlayer.isPlaying()){
//getting metadata.
String iD3Payload = new String(timedMetaData.getMetaData(), StandardCharsets.UTF_8);
//If tag metadata contains "www.nielsen.com", then only sending to SDK
if (null != iD3Payload && iD3Payload.contains("www.nielsen.com"))
{
//getting index
int index = iD3Payload.indexOf("www.nielsen.com");
//getting substring as ID3 tag will be of 249 characters
String id3String = iD3Payload.substring(index, (index + 249));
Log.d(TAG, "TimedMetaData ID3 Tag:" + id3String);
//Sending ID3 tag to SDK.
appSdk.sendID3(id3String);
}
}
}
//Needed only for DTVR video
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra)
{
boolean isInfoHandled = false;
if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE)
{
// Once metadata is available, select an ID3 track in order
// to be able to receive timed metadata updates.
selectId3Track(mp);
isInfoHandled = true;
}
return isInfoHandled;
}
//Selects ID3 tag to receive TimedMetadata.
private void selectId3Track(MediaPlayer mp)
{
try
{
if (mp != null)
{
//Getting the trackinfo of mediaplayer
MediaPlayer.TrackInfo[] tracks = mp.getTrackInfo();
if (tracks.length > 0)
{
//Getting ID3 Pattern
Pattern id3mime = Pattern.compile("mime=.*\\/.*id3.*,", Pattern.CASE_INSENSITIVE);
for (int i = 0; i < tracks.length; i++)
{
//Getting single track from array
MediaPlayer.TrackInfo track = tracks[i];
//Matching track with ID3 pattern
if (id3mime.matcher(track.toString()).find())
{
//Selecting ID3 track to receive timedMetaData.
mp.selectTrack(i);
Log.d(TAG, "Track #" + i + " has been selected ::: " + track);
break;
}
}
}
}
}
catch (Exception e)
{
Log.e(TAG, "Couldn't select ID3 track for MediaPlayer", e);
}
}
}
OptOutActivity
package com.nielsen.simple_playerstandard_android_sdk_7000.activities;
import ...
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());
}
});
NielsenInit nielsenInit = new NielsenInit();
appSdk = nielsenInit.initAppSdk(getApplicationContext(), this);
//Getting the optPut URL from eventTracker
String url = appSdk.userOptOutURLString();
webView.loadUrl(url);
}
@Override
public void onAppSdkEvent(long l, int i, String s) {
}
@Override
protected void onDestroy() {
super.onDestroy();
if (appSdk != null)
{
appSdk.close();
appSdk = null;
}
}
}