AI-generated Key Takeaways
-
The Android PAL SDK, hosted on Google's Maven repository, can be added to your app as a library by including
implementation 'com.google.android.gms:play-services-pal:22.0.0'
in yourapp/build.gradle
file. -
A unique, encrypted "nonce" string, generated by the PAL SDK's
NonceLoader
, is required for each new stream request and can be reused for multiple ad requests within the same stream. -
You need to initialize the
NonceLoader
as early as possible, ideally creating only one instance per user session, to ensure consistent page correlator values and shared stream correlator values for frequency capping and competitive exclusion features. -
To use the generated nonce, you must append it to your ad tag with the
givn
parameter, replacing any prior use of thepaln
parameter, and include the nonce value when making ad requests. -
Playback events such as start, end, ad clicks, and touch interactions must be tracked and sent to the
NonceManager
usingsendPlaybackStart()
,sendPlaybackEnd()
,sendAdClick()
, andsendTouch()
, respectively.
PAL lets you send Google ad signals in your ad requests and during ad playback.
This guide covers adding the Android PAL SDK to your app. To see a sample app that uses PAL to generate a nonce, download the Android example from GitHub.
Add the Android PAL SDK as a library
As of version 18.0.0, the PAL SDK is hosted on Google's Maven repository and can be added to your app as follows:
implementation 'com.google.android.gms:play-services-pal:22.1.0'
Alternatively, the PAL SDK can be downloaded from Google's Maven repository and manually added to your app.
Generate nonce
A nonce is a single encrypted string PAL generates using the NonceLoader
class. PAL requires each stream request to be accompanied by a
unique nonce. However, you can reuse nonces for multiple ad requests
in the same stream. To generate a nonce using the PAL SDK, make the
following changes to import and set up PAL, and create a function to generate
a nonce:
Import and set up PAL by doing the following:
Import PAL classes:
import com.google.ads.interactivemedia.pal.ConsentSettings; import com.google.ads.interactivemedia.pal.NonceLoader; import com.google.ads.interactivemedia.pal.NonceManager; import com.google.ads.interactivemedia.pal.NonceRequest; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import java.util.HashSet; import java.util.Set;
Create private variables to store the
NonceLoader
andNonceManager
instances:private NonceLoader nonceLoader; private NonceManager nonceManager;
Initialize your
NonceLoader
instance with aConsentSettings
instance in theonCreate
method:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 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 isStorageAllowed = getConsentToStorage(); ConsentSettings consentSettings = ConsentSettings.builder().allowStorage(isStorageAllowed).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); adClickButton = findViewById(R.id.send_click_button); logView = findViewById(R.id.log_view); logView.setMovementMethod(new ScrollingMovementMethod()); }
In your app, create one instance of the
NonceLoader
class for each user session. If your app has multiple pages or equivalent constructs, create a newNonceLoader
instance for each page or page-equivalent. By using the sameNonceLoader
instance, you keep the page correlator&correlator
unchanged for the lifetime of a page or a user's session on the app. You still have control over the stream correlator&scor
, which you must reset for each new stream by generating a new nonce.All ad requests of the same stream must share the same
NonceLoader
instance and stream correlator value for frequency capping and competitive exclusion features to happen.Generate a nonce:
public void generateNonceForAdRequest(View view) { logMessage("Generate Nonce Request"); Set supportedApiFrameWorksSet = new HashSet(); // The values 2, 7, and 9 correspond to player support for VPAID 2.0, // OMID 1.0, and SIMID 1.1. supportedApiFrameWorksSet.add(2); supportedApiFrameWorksSet.add(7); supportedApiFrameWorksSet.add(9); NonceRequest nonceRequest = NonceRequest.builder() .descriptionURL("https://example.com/content1") .iconsSupported(true) .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(false) .build(); nonceLoader .loadNonceManager(nonceRequest) .addOnSuccessListener( new OnSuccessListener<NonceManager>() { @Override public void onSuccess(NonceManager manager) { nonceManager = manager; String nonceString = manager.getNonce(); logMessage("Nonce generated"); logMessage(nonceString.substring(0, 20) + "..."); Log.i(LOG_TAG, "Generated nonce: " + nonceString); // From here you would trigger your ad request and move on to initialize content. exampleMakeAdRequest(DEFAULT_AD_TAG + "&givn=" + nonceString); adClickButton.setEnabled(true); } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(Exception error) { logMessage("Nonce generation failed"); Log.e(LOG_TAG, "Nonce generation failed: " + error.getMessage()); } }); }
You only need one nonce for all the ad requests in a single stream playback. For testing purposes, call this function when clicking a button in your test app. The
NonceRequest
parameters set in this guide are example parameters. Set your parameters based on your own app characteristics.This function generates a nonce asynchronously. You must handle both success and failure cases of the nonce request. After the nonce manager is available, retrieve the nonce before you make an ad request using the
nonceManager.getNonce()
method.
Attach nonce to the ad request
To use the generated nonce, append your ad tag with a givn
parameter and the
nonce value before making your ad requests:
// From here you would trigger your ad request and move on to initialize content.
exampleMakeAdRequest(DEFAULT_AD_TAG + "&givn=" + nonceString);
Track playback events
To track playback events, you must set up event handlers to send ad signals to Google:
// Triggered when a user clicks-through on an ad which was requested using a PAL nonce.
public void sendAdClick(View view) {
logMessage("Ad click sent");
if (nonceManager != null) {
nonceManager.sendAdClick();
}
}
// In a typical PAL app, this is called when a user touch or click is detected,
// on the ad other than an ad click-through.
public void onVideoViewTouch(MotionEvent e) {
if (nonceManager != null) {
nonceManager.sendAdTouch(e);
}
}
// In a typical PAL app, this is called when a content playback session starts.
public void sendPlaybackStart() {
logMessage("Playback start");
if (nonceManager != null) {
nonceManager.sendPlaybackStart();
}
}
// In a typical PAL app, this is called when a content playback session ends.
public void sendPlaybackEnd() {
logMessage("Playback end");
if (nonceManager != null) {
nonceManager.sendPlaybackEnd();
}
}
Here is when to call each function in your implementation:
sendPlaybackStart()
: When your video playback session beginssendPlaybackEnd()
: When your video playback session comes to an endsendAdClick()
: Each time the viewer clicks an adsendTouch()
: On every touch interaction with the player
For testing purposes, attach the event handler methods to button click events. In a production implementation, set up your app for player events to call the event handler methods.
(Optional) Send Google Ad Manager signals through third-party ad servers
When you set up your third-party ad server to work with Google Ad Manager, refer to your server's documentation to capture and forward the nonce value in each ad request. The provided example is of an ad request URL with the nonce parameter included. The nonce parameter propagates from the PAL SDK, through your intermediary servers, and then to Ad Manager, enabling better monetization.
Configure your third-party ad server to include the nonce in the server's request to Ad Manager. Here's an example of an ad tag configured inside of the third-party ad server:
'https://pubads.serverside.net/gampad/ads?givn=%%custom_key_for_google_nonce%%&...'
For more details, see the Google Ad Manager Server-side implementation guide.
Ad Manager looks for givn=
to identify the nonce value. The third-party ad
server needs to support some macro of its own, such as
%%custom_key_for_google_nonce%%
, and replace it with the nonce query parameter
you provided in the previous step. More information on how to accomplish this
is available in the third-party ad server's documentation.