Admob Interstitial Ad with Consent Android [GDPR]
AdMob’s Interstitial ads are efficient ad formats that can boost your revenue more effectively than banner ads. Previously, an AdMob Banner Ad was implemented with UMP for user consent. In this tutorial, let’s explore how to implement an AdMob interstitial ad with user consent.
Step 1: Create a new Android project
The MainActivity will be :
MainActivity.java
package com.bigknol.inter.ump.example;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import com.bigknol.slideimage.R;
public class MainActivity extends AppCompatActivity {
Button retryButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_inter_ad_demo);
retryButton = findViewById(R.id.buttonRetry);
retryButton.setOnClickListener(v ->{
});
}
}
activity_main_inter_ad_demo.xml file :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:ads="http://schemas.android.com/apk/res-auto"
tools:context="com.bigknol.inter.ump.example.MainActivity"
tools:ignore="MergeRootFrame"
>
<Button
android:id="@+id/buttonRetry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/retry_game"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.98" />
</androidx.constraintlayout.widget.ConstraintLayout>
Below is the initial screen of the app.
Step 2: Set up menus for Consent Settings
Create a new menu folder if it doesn’t exist in your project.
res > menu
Create a new action_menu.xml file in the above menu folder.
action_menu.xml :
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_more"
android:icon="@android:drawable/ic_menu_preferences"
android:title="@string/more_menu"
app:showAsAction="always"
android:visible="false"/>
</menu>
popup_menu.xml :
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/privacy_settings"
android:title="@string/privacy_settings" />
</menu>
strings.xml
<string name="more_menu" translatable="false">More</string>
<string name="privacy_settings" translatable="false">Privacy Settings</string>
Step 3 : Add dependencies for AdMob and the User Messaging Platform(UMP).
Open the build.gradle(:app) file and add the following dependencies:
implementation 'com.google.android.gms:play-services-ads:22.6.0'
Android UMP
The User Messaging Platform (UMP) is a tool developed by Google to simplify compliance with various privacy and consent regulations, like GDPR and CCPA. It provides a standardized way for apps to handle user consent regarding personalized ads and more.
implementation 'com.google.android.ump:user-messaging-platform:2.1.0'
Step 4: Create a Google Mobile Ads Consent Manager class
GoogleMobileAdsConsentManager.java
public class GoogleMobileAdsConsentManager {
private static GoogleMobileAdsConsentManager instance;
private final ConsentInformation consentInformation;
private GoogleMobileAdsConsentManager(Context context) {
this.consentInformation = UserMessagingPlatform.getConsentInformation(context);
}
public static GoogleMobileAdsConsentManager getInstance(Context context) {
if (instance == null) {
instance = new GoogleMobileAdsConsentManager(context);
}
return instance;
}
public interface OnConsentGatheringCompleteListener {
void consentGatheringComplete(FormError error);
}
public boolean canRequestAds() {
return consentInformation.canRequestAds();
}
public boolean isPrivacyOptionsRequired() {
return consentInformation.getPrivacyOptionsRequirementStatus()
== PrivacyOptionsRequirementStatus.REQUIRED;
}
public void gatherConsent(
Activity activity, OnConsentGatheringCompleteListener onConsentGatheringCompleteListener) {
// For testing purposes, you can force a DebugGeography of EEA or NOT_EEA.
ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(activity)
.setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
.addTestDeviceHashedId("YOUR-DEVICE-HERE")
.build();
ConsentRequestParameters params = new ConsentRequestParameters.Builder()
.setConsentDebugSettings(debugSettings)
.build();
consentInformation.requestConsentInfoUpdate(
activity,
params,
() ->
UserMessagingPlatform.loadAndShowConsentFormIfRequired(
activity,
formError -> {
// Consent has been gathered.
onConsentGatheringCompleteListener.consentGatheringComplete(formError);
}),
requestConsentError ->
onConsentGatheringCompleteListener.consentGatheringComplete(requestConsentError)
);
}
public void showPrivacyOptionsForm(
Activity activity,
OnConsentFormDismissedListener onConsentFormDismissedListener) {
UserMessagingPlatform.showPrivacyOptionsForm(activity, onConsentFormDismissedListener);
}
}
To access the complete class code with useful info: GoogleMobileAdsConsentManager.java
To find the hashed device ID : AdMob Test Ads : How to Setup for Debugging?
Step 4 : Updating MainActivity to manage consent
private static final String AD_UNIT_ID_INTER = "ca-app-pub-3940256099942544/1033173712";
private static final String TAG = "Main Activity";
private final AtomicBoolean isMobileAdsInitializeCalled = new AtomicBoolean(false);
private GoogleMobileAdsConsentManager googleMobileAdsConsentManager;
private AtomicBoolean initialLayoutComplete = new AtomicBoolean(false);
private InterstitialAd interstitialAd;
private boolean adIsLoading;
Initialize the AdMob SDK :
// Log the Mobile Ads SDK version.
Log.d(TAG, "Google Mobile Ads SDK Version: " + MobileAds.getVersion());
// Initialize the Mobile Ads SDK.
MobileAds.initialize(this, new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {}
});
Setting up Consent Management
// setting up consent manager
googleMobileAdsConsentManager =
GoogleMobileAdsConsentManager.getInstance(getApplicationContext());
googleMobileAdsConsentManager.gatherConsent(
this,
consentError -> {
if (consentError != null) {
// Consent not obtained in current session.
Log.w(
TAG,
String.format("%s: %s", consentError.getErrorCode(), consentError.getMessage()));
}
if (googleMobileAdsConsentManager.canRequestAds()) {
initializeMobileAdsSdk();
}
if (googleMobileAdsConsentManager.isPrivacyOptionsRequired()) {
// Regenerate the options menu to include a privacy setting.
invalidateOptionsMenu();
}
});
// This sample attempts to load ads using consent obtained in the previous session.
if (googleMobileAdsConsentManager.canRequestAds()) {
initializeMobileAdsSdk();
}
initializeMobileAdsSdk()
private void initializeMobileAdsSdk() {
if (isMobileAdsInitializeCalled.getAndSet(true)) {
return;
}
// Initialize the Mobile Ads SDK.
MobileAds.initialize(
this,
new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
loadAd();
}
});
// Load an ad.
if (initialLayoutComplete.get()) {
}
}
loadAd():
public void loadAd() {
// Request a new ad if one isn't already loaded.
if (adIsLoading || interstitialAd != null) {
return;
}
adIsLoading = true;
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(
this,
AD_UNIT_ID_INTER,
adRequest,
new InterstitialAdLoadCallback() {
@Override
public void onAdLoaded(@NonNull InterstitialAd interstitialAd) {
// The mInterstitialAd reference will be null until
// an ad is loaded.
MainActivity.this.interstitialAd = interstitialAd;
adIsLoading = false;
Log.i(TAG, "onAdLoaded");
// Toast.makeText(HomeActivity.this, "onAdLoaded()", Toast.LENGTH_SHORT).show();
interstitialAd.setFullScreenContentCallback(
new FullScreenContentCallback() {
@Override
public void onAdDismissedFullScreenContent() {
// Called when fullscreen content is dismissed.
// Make sure to set your reference to null so you don't
// show it a second time.
MainActivity.this.interstitialAd = null;
Log.d("TAG", "The ad was dismissed.");
}
@Override
public void onAdFailedToShowFullScreenContent(AdError adError) {
// Called when fullscreen content failed to show.
// Make sure to set your reference to null so you don't
// show it a second time.
MainActivity.this.interstitialAd = null;
Log.d("TAG", "The ad failed to show.");
}
@Override
public void onAdShowedFullScreenContent() {
// Called when fullscreen content is shown.
Log.d("TAG", "The ad was shown.");
}
});
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
// Handle the error
Log.i(TAG, loadAdError.getMessage());
interstitialAd = null;
adIsLoading = false;
String error =
String.format(
"domain: %s, code: %d, message: %s",
loadAdError.getDomain(), loadAdError.getCode(), loadAdError.getMessage());
// Toast.makeText(HomeActivity.this, "onAdFailedToLoad() with error: " + error, Toast.LENGTH_SHORT).show();
}
});
}
Let’s override onCreateOptionsMenu :
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
Enabling Privacy Options for GDPR-Affected Areas
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.action_menu, menu);
MenuItem moreMenu = menu.findItem(R.id.action_more);
moreMenu.setVisible(googleMobileAdsConsentManager.isPrivacyOptionsRequired());
return true;
}
onOptionsItemSelected:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
View menuItemView = findViewById(item.getItemId());
PopupMenu popup = new PopupMenu(this, menuItemView);
popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
popup.show();
popup.setOnMenuItemClickListener(
popupMenuItem -> {
if (popupMenuItem.getItemId() == R.id.privacy_settings) {
// Handle changes to user consent.
googleMobileAdsConsentManager.showPrivacyOptionsForm(
this,
formError -> {
if (formError != null) {
Toast.makeText(this, formError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
return true;
}
return false;
});
return super.onOptionsItemSelected(item);
}
Let’s show the AdMob interstitial ad with user consent :
private void showInterstitial() {
// Show the ad if it's ready. Otherwise restart the game.
if (interstitialAd != null) {
interstitialAd.show(this);
} else {
if (googleMobileAdsConsentManager.canRequestAds()) {
loadAd();
}
}
}
Clicking on the Retry Game button will generate the Interstitial ad.
retryButton = findViewById(R.id.buttonRetry);
retryButton.setOnClickListener(v ->{
showInterstitial();
});
Changes to Android Manifest File:
Permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
APPLICATION_ID:
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713" />
MainActivity.java [Full Code]
package com.bigknol.inter.ump.example;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.Toast;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import java.util.concurrent.atomic.AtomicBoolean;
public class MainActivity extends AppCompatActivity {
Button retryButton;
private static final String AD_UNIT_ID_INTER = "ca-app-pub-3940256099942544/1033173712";
private static final String TAG = "Main Activity";
private final AtomicBoolean isMobileAdsInitializeCalled = new AtomicBoolean(false);
private GoogleMobileAdsConsentManager googleMobileAdsConsentManager;
private AtomicBoolean initialLayoutComplete = new AtomicBoolean(false);
private InterstitialAd interstitialAd;
private boolean adIsLoading;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_inter_ad_demo);
// Log the Mobile Ads SDK version.
Log.d(TAG, "Google Mobile Ads SDK Version: " + MobileAds.getVersion());
// Initialize the Mobile Ads SDK.
MobileAds.initialize(this, new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {}
});
// setting up consent manager
googleMobileAdsConsentManager =
GoogleMobileAdsConsentManager.getInstance(getApplicationContext());
googleMobileAdsConsentManager.gatherConsent(
this,
consentError -> {
if (consentError != null) {
// Consent not obtained in current session.
Log.w(
TAG,
String.format("%s: %s", consentError.getErrorCode(), consentError.getMessage()));
}
if (googleMobileAdsConsentManager.canRequestAds()) {
initializeMobileAdsSdk();
}
if (googleMobileAdsConsentManager.isPrivacyOptionsRequired()) {
// Regenerate the options menu to include a privacy setting.
invalidateOptionsMenu();
}
});
// This sample attempts to load ads using consent obtained in the previous session.
if (googleMobileAdsConsentManager.canRequestAds()) {
initializeMobileAdsSdk();
}
retryButton = findViewById(R.id.buttonRetry);
retryButton.setOnClickListener(v ->{
showInterstitial();
});
}
private void initializeMobileAdsSdk() {
if (isMobileAdsInitializeCalled.getAndSet(true)) {
return;
}
// Initialize the Mobile Ads SDK.
MobileAds.initialize(
this,
new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
loadAd();
}
});
// Load an ad.
if (initialLayoutComplete.get()) {
}
}
public void loadAd() {
// Request a new ad if one isn't already loaded.
if (adIsLoading || interstitialAd != null) {
return;
}
adIsLoading = true;
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(
this,
AD_UNIT_ID_INTER,
adRequest,
new InterstitialAdLoadCallback() {
@Override
public void onAdLoaded(@NonNull InterstitialAd interstitialAd) {
// The mInterstitialAd reference will be null until
// an ad is loaded.
MainActivity.this.interstitialAd = interstitialAd;
adIsLoading = false;
Log.i(TAG, "onAdLoaded");
// Toast.makeText(HomeActivity.this, "onAdLoaded()", Toast.LENGTH_SHORT).show();
interstitialAd.setFullScreenContentCallback(
new FullScreenContentCallback() {
@Override
public void onAdDismissedFullScreenContent() {
// Called when fullscreen content is dismissed.
// Make sure to set your reference to null so you don't
// show it a second time.
MainActivity.this.interstitialAd = null;
Log.d("TAG", "The ad was dismissed.");
}
@Override
public void onAdFailedToShowFullScreenContent(AdError adError) {
// Called when fullscreen content failed to show.
// Make sure to set your reference to null so you don't
// show it a second time.
MainActivity.this.interstitialAd = null;
Log.d("TAG", "The ad failed to show.");
}
@Override
public void onAdShowedFullScreenContent() {
// Called when fullscreen content is shown.
Log.d("TAG", "The ad was shown.");
}
});
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
// Handle the error
Log.i(TAG, loadAdError.getMessage());
interstitialAd = null;
adIsLoading = false;
String error =
String.format(
"domain: %s, code: %d, message: %s",
loadAdError.getDomain(), loadAdError.getCode(), loadAdError.getMessage());
// Toast.makeText(HomeActivity.this, "onAdFailedToLoad() with error: " + error, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.action_menu, menu);
MenuItem moreMenu = menu.findItem(R.id.action_more);
moreMenu.setVisible(googleMobileAdsConsentManager.isPrivacyOptionsRequired());
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
View menuItemView = findViewById(item.getItemId());
PopupMenu popup = new PopupMenu(this, menuItemView);
popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
popup.show();
popup.setOnMenuItemClickListener(
popupMenuItem -> {
if (popupMenuItem.getItemId() == R.id.privacy_settings) {
// Handle changes to user consent.
googleMobileAdsConsentManager.showPrivacyOptionsForm(
this,
formError -> {
if (formError != null) {
Toast.makeText(this, formError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
return true;
}
return false;
});
return super.onOptionsItemSelected(item);
}
private void showInterstitial() {
// Show the ad if it's ready. Otherwise restart the game.
if (interstitialAd != null) {
interstitialAd.show(this);
} else {
if (googleMobileAdsConsentManager.canRequestAds()) {
loadAd();
}
}
}
}
Ensure that you’ve updated the DEBUG_GEOGRAPHY_EEA and Device Hashed ID from Logcat.
Step 5: Run the app
Run the app to test the user consent form for AdMob Interstitial implementation.
First Time User :
Tap the Retry Game button :
In conclusion, implementing AdMob Interstitial Ads with GDPR consent ensures compliance with privacy regulations while allowing for the effective integration of these ads within the app’s user experience.