Under the Google EU User Consent Policy, you must make certain disclosures to your users in the European Economic Area (EEA) along with the UK and obtain their consent to use cookies or other local storage, where legally required, and to use personal data (such as AdID) to serve ads. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR).
To support publishers in meeting their duties under this policy, Google offers the User Messaging Platform (UMP) SDK. The UMP SDK has been updated to support the latest IAB standards. All of these configurations can now conveniently be handled in Ad Manager privacy & messaging.
Prerequisites
- Complete the Get Started guide
- Android API level 21 or higher
- If you're working on GDPR-related requirements, read How IAB requirements affect EU consent messages
Create a message type
Create user messages with one of the available user message types under the Privacy & messaging tab of your Ad Manager account. The UMP SDK attempts to display a user message created from the Ad Manager Application ID set in your project. If no message is configured for your application, the SDK returns an error.
For more details, see About privacy and messaging.
Install with Gradle
Add the dependency for the Google User Messaging Platform SDK to your module's
app-level Gradle file, normally app/build.gradle
:
dependencies {
implementation 'com.google.android.ump:user-messaging-platform:2.1.0'
}
After making the changes to your app's build.gradle
, be sure to sync your
project with Gradle files.
Request for consent information
You should request an update of the user's consent information at every app
launch, using requestConsentInfoUpdate()
. This determines
whether your user needs to provide consent if they haven't done so already, or
if their consent has expired.
Here is an example of how to check the status from the MainActivity
in the
onCreate()
method.
Java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.ump.ConsentInformation;
import com.google.android.ump.ConsentRequestParameters;
import com.google.android.ump.FormError;
import com.google.android.ump.UserMessagingPlatform;
public class MainActivity extends AppCompatActivity {
private ConsentInformation consentInformation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set tag for under age of consent. false means users are not under age
// of consent.
ConsentRequestParameters params = new ConsentRequestParameters
.Builder()
.setTagForUnderAgeOfConsent(false)
.build();
consentInformation = UserMessagingPlatform.getConsentInformation(this);
consentInformation.requestConsentInfoUpdate(
this,
params,
(OnConsentInfoUpdateSuccessListener) () -> {
// TODO: Load and show the consent form.
},
(OnConsentInfoUpdateFailureListener) requestConsentError -> {
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
requestConsentError.getErrorCode(),
requestConsentError.getMessage()));
});
}
}
Kotlin
package com.example.myapplication
import com.google.android.ump.ConsentInformation
import com.google.android.ump.ConsentInformation.OnConsentInfoUpdateFailureListener
import com.google.android.ump.ConsentInformation.OnConsentInfoUpdateSuccessListener
import com.google.android.ump.ConsentRequestParameters
import com.google.android.ump.UserMessagingPlatform
class MainActivity : AppCompatActivity() {
private lateinit var consentInformation: ConsentInformation
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Set tag for under age of consent. false means users are not under age
// of consent.
val params = ConsentRequestParameters
.Builder()
.setTagForUnderAgeOfConsent(false)
.build()
consentInformation = UserMessagingPlatform.getConsentInformation(this)
consentInformation.requestConsentInfoUpdate(
this,
params,
ConsentInformation.OnConsentInfoUpdateSuccessListener {
// TODO: Load and show the consent form.
},
ConsentInformation.OnConsentInfoUpdateFailureListener {
requestConsentError ->
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
requestConsentError.errorCode(),
requestConsentError.message()))
})
}
}
Load and show a consent form if required
After you have received the most up-to-date consent status, call
loadAndShowConsentFormIfRequired()
on the
ConsentForm
class to load a consent form. If the
consent status is required, the SDK loads a form and immediately presents it
from the provided activity. The callback
is called after the form is dismissed. If consent is not required, the callback
is called immediately.
Java
public class MainActivity extends AppCompatActivity {
private ConsentInformation consentInformation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set tag for under age of consent. false means users are not under age
// of consent.
ConsentRequestParameters params = new ConsentRequestParameters
.Builder()
.setTagForUnderAgeOfConsent(false)
.build();
consentInformation = UserMessagingPlatform.getConsentInformation(this);
consentInformation.requestConsentInfoUpdate(
this,
params,
(OnConsentInfoUpdateSuccessListener) () -> {
UserMessagingPlatform.loadAndShowConsentFormIfRequired(
this,
(OnConsentFormDismissedListener) loadAndShowError -> {
if (loadAndShowError != null) {
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
loadAndShowError.getErrorCode(),
loadAndShowError.getMessage()));
}
// Consent has been gathered.
}
)
},
(OnConsentInfoUpdateFailureListener) requestConsentError -> {
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
requestConsentError.getErrorCode(),
requestConsentError.getMessage()));
});
}
}
Kotlin
class MainActivity : AppCompatActivity() {
private lateinit var consentInformation: ConsentInformation
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Set tag for under age of consent. false means users are not under age
// of consent.
val params = ConsentRequestParameters
.Builder()
.setTagForUnderAgeOfConsent(false)
.build()
consentInformation = UserMessagingPlatform.getConsentInformation(this)
consentInformation.requestConsentInfoUpdate(
this,
params,
ConsentInformation.OnConsentInfoUpdateSuccessListener {
UserMessagingPlatform.loadAndShowConsentFormIfRequired(
this@MainActivity,
ConsentForm.OnConsentFormDismissedListener {
loadAndShowError ->
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
loadAndShowError.errorCode(),
loadAndShowError.message()))
// Consent has been gathered.
}
)
},
ConsentInformation.OnConsentInfoUpdateFailureListener {
requestConsentError ->
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
requestConsentError.errorCode(),
requestConsentError.message()))
})
}
}
If you need to perform any actions after the user has made a choice or dismissed the form, place that logic in the callback for your form.
Request ads
Before requesting ads in your app, check if you have obtained consent
from the user using canRequestAds()
. There are two
places to check while gathering consent:
- Once consent has been gathered in the current session.
- Immediately after you have called
requestConsentInfoUpdate()
. It is possible consent has been obtained in the previous session. As a latency best practice, we recommend not waiting for the callback to complete so you can start loading ads as soon as possible after your app launches.
If an error occurs during the consent gathering process, you should still attempt to request ads. The UMP SDK uses the consent status from the previous session.
Java
public class MainActivity extends AppCompatActivity {
private ConsentInformation consentInformation;
// Use an atomic boolean to initialize the Google Mobile Ads SDK and load ads once.
private final AtomicBoolean isMobileAdsInitializeCalled = new AtomicBoolean(false);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set tag for under age of consent. false means users are not under age
// of consent.
ConsentRequestParameters params = new ConsentRequestParameters
.Builder()
.setTagForUnderAgeOfConsent(false)
.build();
consentInformation = UserMessagingPlatform.getConsentInformation(this);
consentInformation.requestConsentInfoUpdate(
this,
params,
(OnConsentInfoUpdateSuccessListener) () -> {
UserMessagingPlatform.loadAndShowConsentFormIfRequired(
this,
(OnConsentFormDismissedListener) loadAndShowError -> {
if (loadAndShowError != null) {
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
loadAndShowError.getErrorCode(),
loadAndShowError.getMessage()));
}
// Consent has been gathered.
if (consentInformation.canRequestAds) {
initializeMobileAdsSdk();
}
}
)
},
(OnConsentInfoUpdateFailureListener) requestConsentError -> {
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
requestConsentError.getErrorCode(),
requestConsentError.getMessage()));
});
// Check if you can initialize the Google Mobile Ads SDK in parallel
// while checking for new consent information. Consent obtained in
// the previous session can be used to request ads.
if (consentInformation.canRequestAds) {
initializeMobileAdsSdk();
}
}
private void initializeMobileAdsSdk() {
if (isMobileAdsInitializeCalled.getAndSet(true)) {
return;
}
// Initialize the Google Mobile Ads SDK.
MobileAds.initialize(this);
// TODO: Request an ad.
// InterstitialAd.load(...);
}
}
Kotlin
class MainActivity : AppCompatActivity() {
private lateinit var consentInformation: ConsentInformation
// Use an atomic boolean to initialize the Google Mobile Ads SDK and load ads once.
private var isMobileAdsInitializeCalled = AtomicBoolean(false)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Set tag for under age of consent. false means users are not under age
// of consent.
val params = ConsentRequestParameters
.Builder()
.setTagForUnderAgeOfConsent(false)
.build()
consentInformation = UserMessagingPlatform.getConsentInformation(this)
consentInformation.requestConsentInfoUpdate(
this,
params,
ConsentInformation.OnConsentInfoUpdateSuccessListener {
UserMessagingPlatform.loadAndShowConsentFormIfRequired(
this@MainActivity,
ConsentForm.OnConsentFormDismissedListener {
loadAndShowError ->
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
loadAndShowError.errorCode(),
loadAndShowError.message()))
// Consent has been gathered.
if (consentInformation.canRequestAds) {
initializeMobileAdsSdk()
}
}
)
},
ConsentInformation.OnConsentInfoUpdateFailureListener {
requestConsentError ->
// Consent gathering failed.
Log.w(TAG, String.format("%s: %s",
requestConsentError.errorCode(),
requestConsentError.message()))
})
// Check if you can initialize the Google Mobile Ads SDK in parallel
// while checking for new consent information. Consent obtained in
// the previous session can be used to request ads.
if (consentInformation.canRequestAds) {
initializeMobileAdsSdk()
}
}
private fun initializeMobileAdsSdk() {
if (isMobileAdsInitializeCalled.get()) {
return
}
isMobileAdsInitializeCalled.set(true)
// Initialize the Google Mobile Ads SDK.
MobileAds.initialize(this)
// TODO: Request an ad.
// InterstitialAd.load(...)
}
}
Testing
If you want to test the integration in your app as you're developing, follow the steps below to programmatically register your test device.
- Call
requestConsentInfoUpdate()
. Check the log output for a message that looks like the one below, which shows you your device ID and how to add it as a test device:
Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231") to set this as a debug device.
Copy your test device ID to your clipboard.
Modify your code to call
DebugGeography.TestDeviceHashedIds
and pass in a list of your test device IDs.
Java
ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
.addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
.build();
ConsentRequestParameters params = new ConsentRequestParameters
.Builder()
.setConsentDebugSettings(debugSettings)
.build();
consentInformation = UserMessagingPlatform.getConsentInformation(this);
// Include the ConsentRequestParameters in your consent request.
consentInformation.requestConsentInfoUpdate(
this,
params,
...
);
Kotlin
val debugSettings = ConsentDebugSettings.Builder(this)
.addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
.build()
val params = ConsentRequestParameters
.Builder()
.setConsentDebugSettings(debugSettings)
.build()
consentInformation = UserMessagingPlatform.getConsentInformation(this)
// Include the ConsentRequestParameters in your consent request.
consentInformation.requestConsentInfoUpdate(
this,
params,
...
)
Force a geography
The UMP SDK provides a way to test your app's behavior as though the device was
located in the EEA or UK using the setDebugGeography
method which takes a DebugGeography
on ConsentDebugSettings.Builder
. Note that
debug settings only work on test devices.
Java
ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
.setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
.addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
.build();
ConsentRequestParameters params = new ConsentRequestParameters
.Builder()
.setConsentDebugSettings(debugSettings)
.build();
consentInformation = UserMessagingPlatform.getConsentInformation(this);
// Include the ConsentRequestParameters in your consent request.
consentInformation.requestConsentInfoUpdate(
this,
params,
...
);
Kotlin
val debugSettings = ConsentDebugSettings.Builder(this)
.setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
.addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
.build()
val params = ConsentRequestParameters
.Builder()
.setConsentDebugSettings(debugSettings)
.build()
consentInformation = UserMessagingPlatform.getConsentInformation(this)
// Include the ConsentRequestParameters in your consent request.
consentInformation.requestConsentInfoUpdate(
this,
params,
...
)
Reset consent state
In testing your app with the UMP SDK, you might find it helpful to reset the
state of the SDK so that you can simulate a user's first install experience.
The SDK provides the reset()
method to do this.
Java
consentInformation.reset();
Kotlin
consentInformation.reset()