Get Started

Stay organized with collections Save and categorize content based on your preferences.

Prerequisites

  • The Android PAL SDK.

Create a new application, and add the Android PAL SDK as a library.

As of version 18.0.0, the PAL SDK is now hosted on Google's Maven repository and can be added to your application as follows:

app/build.gradle

...

dependencies {
    implementation 'com.google.android.gms:play-services-pal:20.0.1'

    ...
}

Alternatively, the PAL SDK can be downloaded from Google's Maven repository and manually added to your app.

Generate a Nonce

A "nonce" is a single encrypted string generated by PAL via the NonceLoader. The PAL SDK requires each new stream request to be accompanied by a newly generated nonce. However, nonces may be reused for multiple ad requests within the same stream. To generate a nonce using the PAL SDK, you'll be making changes to MyActivity.java.

First, you need to import the PAL SDK, create some private properties to store your NonceLoader and NonceManager, and initialize your NonceLoader:

import android.app.Activity;
import android.os.Bundle;
import com.google.ads.interactivemedia.pal.NonceLoader;
import com.google.ads.interactivemedia.pal.NonceManager;
import com.google.ads.interactivemedia.pal.NonceRequest;
import com.google.ads.interactivemedia.pal.ConsentSettings;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

import java.util.HashSet;
import java.util.Set;

public class MainActivity extends Activity {
...
  private NonceLoader nonceLoader;
  private NonceManager nonceManager = null;
  private ConsentSettings consentSettings;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // The default value for allowStorage() is false, but can be
    // changed once the appropriate consent has been gathered. The
    // getConsentToStorage() method is a placeholder for the publisher's own
    // method of obtaining user consent, either by integrating with a CMP or
    // based on other methods the publisher chooses to handle storage consent.

    boolean isConsentToStorage = getConsentToStorage();

    videoView = findViewById(R.id.video_view);
    videoView.setOnTouchListener(this::onVideoViewTouch);

    consentSettings = ConsentSettings.builder()
            .allowStorage(isConsentToStorage)
            .build();

    // It is important to instantiate the NonceLoader as early as possible to
    // allow it to initialize and preload data for a faster experience when
    // loading the NonceManager. A new NonceLoader will need to be instantiated
    //if the ConsentSettings change for the user.
    nonceLoader = new NonceLoader(this, consentSettings);
    ...
  }

Next, create a function to trigger nonce generation. In a real implementation, this function would be called when initializing your video stream, but for the purposes of testing this functionality, you may prefer to apply this to the click event of a button in your app.

This function will trigger nonce generation asynchronously, so you need to implement an AsyncTask to handle success or failure of the nonce request:

  public void generateNonceForAdRequest() {
    Set supportedApiFrameWorksSet = new HashSet();
    supportedApiFrameWorksSet.add(2);
    supportedApiFrameWorksSet.add(7);
    supportedApiFrameWorksSet.add(9);

    NonceRequest nonceRequest = NonceRequest.builder()
        .descriptionURL("https://example.com/content1")
        .omidVersion("1.0.0")
        .omidPartnerVersion("6.2.1")
        .omidPartnerName("Example Publisher")
        .playerType("ExamplePlayerType")
        .playerVersion("1.0.0")
        .ppid("testPpid")
        .sessionId("Sample SID")
        .supportedApiFrameworks(supportedApiFrameWorksSet)
        .videoPlayerHeight(480)
        .videoPlayerWidth(640)
        .willAdAutoPlay(true)
        .willAdPlayMuted(true)
        .build();
    NonceCallbackImpl callback = new NonceCallbackImpl();
    nonceLoader
        .loadNonceManager(nonceRequest)
        .addOnSuccessListener(callback)
        .addOnFailureListener(callback);
  }

  private class NonceCallbackImpl implements OnSuccessListener, OnFailureListener {
    @Override
    public void onSuccess(NonceManager manager) {
      nonceManager = manager;
      String nonceString = manager.getNonce();
      Log.i("PALSample", "Generated nonce: " + nonceString);
      // from here you would trigger your ad request and move on to initialize content
    }

    @Override
    public void onFailure(Exception error) {
      Log.e("PALSample", "Nonce generation failed: " + error.getMessage());
    }
  }

Once a nonce Manager is created, the nonce can be retrieved at any time, using nonceManager.getNonce().

Lastly, you need to implement various event handlers for your player. For testing purposes, you may attach these to button click events, but in a real implementation these would be triggered by the appropriate player events:

  public void sendAdClick() {
    if (nonceManager != null) {
      nonceManager.sendAdClick();
    }
  }

  public void sendPlaybackStart() {
    if (nonceManager != null) {
      nonceManager.sendPlaybackStart();
    }
  }

  public void sendPlaybackEnd() {
    if (nonceManager != null) {
      nonceManager.sendPlaybackEnd();
    }
  }

  public void onVideoViewTouch(MotionEvent e) {
    if (nonceManager != null) {
      nonceManager.sendTouch(e);
    }
  }

In your implementation, sendPlaybackStart should be called once your video playback session begins. sendPlaybackEnd should be called once your video playback session comes to an end. sendAdClick should be called each time the viewer clicks an ad. sendTouch should be called on every touch interaction with the player.