AdMob UMP Android : Implementing Banner Ad with User Consent
When Integrating AdMob into mobile apps, developers need to implement consent mechanism to request user’s permission for data collection. This can involve displaying dialog boxes or prompts that explicitly outline the data being collected and the purposes for which it will be used. AdMob UMP Android implementation with a banner ad:
Importance of GDPR User Consent in Your App
AdMob’s official notification states that every AdMob-enabled app must include a consent form by January 16, 2024. If you miss the deadline, AdMob will display a default message using an interstitial or app open ad unit whenever possible.
AdMob UMP (User Messaging Platform) for Android
UMP, or the User Messaging Platform, is an Android tool that developers use to manage and request user consent specifically for personalized ads within mobile applications.
Developers can seamlessly prioritize user privacy preferences by utilizing this platform to implement consent mechanisms effectively.
Admob Banner Ad with UMP (User Consent)
Step by Step Guide for implementing AdMob UMP Consent in an Android app:
Step 1: Create an app
Create a new Android project in Android Studio. You can also use your existing app.
Step 2: Include A Menu Option
Ensure your app includes an option (menu) for displaying privacy settings; it’s crucial. This menu will only appear for users in countries where privacy consent is required.
Include the following:
Place in your project : app > res > menu
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
Include the following strings:
<string name="more_menu" translatable="false">More</string>
<string name="privacy_settings" translatable="false">Privacy Settings</string>
Step 3: Add UMP Dependency
Open the build.gradle(:app) file and the following dependency:
implementation 'com.google.android.ump:user-messaging-platform:2.1.0'
AdMob SDK:
implementation 'com.google.android.gms:play-services-ads:22.6.0'
Step 4: Adding Google Mobile Ads Consent Manager Class
Create a new class called ‘GoogleMobileAdsConsentManager‘ and place this class in a package called gmacm
Create an instance of GoogleMobileAdsConsentManger
private static GoogleMobileAdsConsentManager instance;
Declare consent information as below :
private final ConsentInformation consentInformation;
Include private and public constructors:
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;
}
Define an interface for a callback to trigger upon the completion of consent gathering.
public interface OnConsentGatheringCompleteListener {
void consentGatheringComplete(FormError error);
}
Auxiliary variable used to ascertain the necessity of the privacy options form.
public boolean canRequestAds() {
return consentInformation.canRequestAds();
}
public boolean isPrivacyOptionsRequired() {
return consentInformation.getPrivacyOptionsRequirementStatus()
== PrivacyOptionsRequirementStatus.REQUIRED;
}
Gathering Consent
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("")
.build();
ConsentRequestParameters params = new ConsentRequestParameters.Builder()
.setConsentDebugSettings(debugSettings)
.build();
// Requesting an update to consent information should be called on every app launch.
consentInformation.requestConsentInfoUpdate(
activity,
params,
() ->
UserMessagingPlatform.loadAndShowConsentFormIfRequired(
activity,
formError -> {
// Consent has been gathered.
onConsentGatheringCompleteListener.consentGatheringComplete(formError);
}),
requestConsentError ->
onConsentGatheringCompleteListener.consentGatheringComplete(requestConsentError)
);
To find the hashed device ID : AdMob Test Ads : How to Setup for Debugging?
Showing the Privacy Options Form in Our App
public void showPrivacyOptionsForm(
Activity activity,
OnConsentFormDismissedListener onConsentFormDismissedListener) {
UserMessagingPlatform.showPrivacyOptionsForm(activity, onConsentFormDismissedListener);
}
You can find the complete source code: GoogleMobileAdsConsentManager.java
Step 5: Setting up MainActivity / HomeActivity
public class HomeActivity extends AppCompatActivity {
private static final String TAG = "Home Activity";
private final AtomicBoolean isMobileAdsInitializeCalled = new AtomicBoolean(false);
private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/6300978111";
private GoogleMobileAdsConsentManager googleMobileAdsConsentManager;
private AdView adView;
private FrameLayout bannerAdContainer;
private AtomicBoolean initialLayoutComplete = new AtomicBoolean(false);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
bannerAdContainer = findViewById(R.id.BannerContainer);
//.. YOUR APP CODE
}
}
activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.bigknol.app.HomeActivity"
tools:showIn="@layout/app_bar_home"
tools:ignore="MergeRootFrame">
<GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="0dp"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="0dp"
android:padding="9dp"
android:layout_above="@+id/BannerContainer"
/>
<FrameLayout
android:id="@+id/BannerContainer"
android:layout_marginTop="1dp"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
Inside onCreate() :
// 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) {}
});
googleMobileAdsConsentManager =
GoogleMobileAdsConsentManager.getInstance(getApplicationContext());
googleMobileAdsConsentManager.gatherConsent(
this,
consentError -> {
if (consentError != null) {
Log.w(
TAG,
String.format("%s: %s", consentError.getErrorCode(), consentError.getMessage()));
}
if (googleMobileAdsConsentManager.canRequestAds()) {
initializeMobileAdsSdk();
}
if (googleMobileAdsConsentManager.isPrivacyOptionsRequired()) {
invalidateOptionsMenu();
}
});
if (googleMobileAdsConsentManager.canRequestAds()) {
initializeMobileAdsSdk();
}
bannerAdContainer
.getViewTreeObserver()
.addOnGlobalLayoutListener(
() -> {
if (!initialLayoutComplete.getAndSet(true)
&& googleMobileAdsConsentManager.canRequestAds()) {
loadBanner();
}
});
onCreateOptionsMenu of HomeActivity / MainActivity.java :
@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 will be :
@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);
}
loadBanner() method:
private void loadBanner() {
adView = new AdView(this);
adView.setAdUnitId(AD_UNIT_ID);
AdSize adSize = getAdSize();
adView.setAdSize(adSize);
AdRequest adRequest =
new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
bannerAdContainer.addView(adView);
adView.loadAd(adRequest);
}
getAdSize() method:
private AdSize getAdSize() {
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
float density = outMetrics.density;
float adWidthPixels = bannerAdContainer.getWidth();
if (adWidthPixels == 0) {
adWidthPixels = outMetrics.widthPixels;
}
int adWidth = (int) (adWidthPixels / density);
return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, adWidth);
}
Step 6: Initialize the Mobile Ads SDK
private void initializeMobileAdsSdk() {
if (isMobileAdsInitializeCalled.getAndSet(true)) {
return;
}
// Initialize the Mobile Ads SDK.
MobileAds.initialize(
this,
new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
}
});
// Load an ad.
if (initialLayoutComplete.get()) {
loadBanner();
}
}
Other Changes:
@Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
@Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
/** Called before the activity is destroyed */
@Override
public void onDestroy() {
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
Android Manifest :
Permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />