Prerequisites
Read How IAB requirements affect EU consent messages.
Introduction
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, which replaces the previous open source Consent SDK. The UMP SDK has been updated to support the latest IAB standards. We've also simplified the process of setting up consent forms and listing ad partners. All of these configurations can now conveniently be handled in Ad Manager Privacy & messaging.
It is a best practice to load a form every time the user launches your app, even if you determine consent is not required, so that the form is ready to display in case the user wishes to change their consent setting.
This guide walks you through how to install the SDK, implement the IAB solutions, and enable testing features.
Install with Gradle
Include the library in your app's build.gradle:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.android.ump:user-messaging-platform:2.0.0'
}
Don't forget to sync Gradle when you're finished.
Add app ID to AndroidManifest.xml
Obtain your app ID from the Mobile apps section of Ad Manager:
Add your app ID to your AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.rewardedinterstitialexample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="YOUR-APP-ID"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Using the SDK
The SDK is designed to be used in a linear fashion. The steps for using the SDK are:
- Request the latest consent information.
- Check if consent is required.
- Check if a form is available and if so load a form.
- Present the form.
- Provide a way for users to change their consent.
Request the latest consent information
It is recommended that you request an update of the consent information at every app launch. This will determine whether or not your user needs to provide consent.
Java
import android.os.Bundle; import com.google.android.ump.ConsentForm; 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; private ConsentForm consentForm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set tag for underage of consent. Here false means users are not underage. ConsentRequestParameters params = new ConsentRequestParameters .Builder() .setTagForUnderAgeOfConsent(false) .build(); consentInformation = UserMessagingPlatform.getConsentInformation(this); consentInformation.requestConsentInfoUpdate( this, params, new ConsentInformation.OnConsentInfoUpdateSuccessListener() { @Override public void onConsentInfoUpdateSuccess() { // The consent information state was updated. // You are now ready to check if a form is available. } }, new ConsentInformation.OnConsentInfoUpdateFailureListener() { @Override public void onConsentInfoUpdateFailure(FormError formError) { // Handle the error. } }); } }
Kotlin
import android.os.Bundle import com.google.android.ump.* class MainActivity : AppCompactActivity() { private lateinit var consentInformation: ConsentInformation private var consentForm: ConsentForm? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Set tag for underage of consent. Here false means users are not underage. val params = ConsentRequestParameters.Builder() .setTagForUnderAgeOfConsent(false) .build() consentInformation = UserMessagingPlatform.getConsentInformation(this) consentInformation.requestConsentInfoUpdate( this, params, { // The consent information state was updated. // You are now ready to check if a form is available. }, { formError -> // Handle the error. } ) } }
Load a form if available
Once you've determined that you will ask a user for consent, the next step is to determine if a form is available.
There are a variety of reasons why a form may not be available, such as:
- The user has limited ad tracking enabled.
- You tagged the user as under the age of consent.
To check if a form is available, use the
isConsentFormAvailable()
method on the ConsentInformation
instance. Add a wrapper method for loading a
form:
Java
... consentInformation.requestConsentInfoUpdate( this, params, new ConsentInformation.OnConsentInfoUpdateSuccessListener() { @Override public void onConsentInfoUpdateSuccess() { // The consent information state was updated. // You are now ready to check if a form is available. if (consentInformation.isConsentFormAvailable()) { loadForm(); } } }, new ConsentInformation.OnConsentInfoUpdateFailureListener() { @Override public void onConsentInfoUpdateFailure(FormError formError) { // Handle the error. } }); } public void loadForm() { }
Kotlin
... consentInformation.requestConsentInfoUpdate( this, params, { // The consent information state was updated. // You are now ready to check if a form is available. if (consentInformation.isConsentFormAvailable) { loadForm() } }, { formError -> // Handle the error. } ) } private fun loadForm() { }
To load the form you will use the static loadConsentForm()
method on the
UserMessagingPlatform
class. This method must only be called from the main
thread. Alter your loadForm()
method like so:
Java
public void loadForm() { UserMessagingPlatform.loadConsentForm( this, new UserMessagingPlatform.OnConsentFormLoadSuccessListener() { @Override public void onConsentFormLoadSuccess(ConsentForm consentForm) { MainActivity.this.consentForm = consentForm; } }, new UserMessagingPlatform.OnConsentFormLoadFailureListener() { @Override public void onConsentFormLoadFailure(FormError formError) { // Handle the error. } }); }
Kotlin
private fun loadForm() { UserMessagingPlatform.loadConsentForm( this, { consentForm -> this.consentForm = consentForm }, { formError -> // Handle the error. } ) }
Present the form if required
To present the form, use the show()
method on the ConsentForm
instance. You
should determine if the user requires consent prior to presenting the form. To
check if consent is required, check the getConsentStatus()
method on the
ConsentInformation
object, which returns an enum of type
ConsentInformation.ConsentStatus
. There are four possible values:
ConsentStatus.UNKNOWN
: Unknown consent status.ConsentStatus.REQUIRED
: User consent required but not yet obtained.ConsentStatus.NOT_REQUIRED
: User consent not required. For example, the user is not in the EEA or the UK.ConsentStatus.OBTAINED
: User consent obtained. Personalization not defined.
Alter your loadForm()
method like so:
Java
public void loadForm() { UserMessagingPlatform.loadConsentForm( this, new UserMessagingPlatform.OnConsentFormLoadSuccessListener() { @Override public void onConsentFormLoadSuccess(ConsentForm consentForm) { MainActivity.this.consentForm = consentForm; if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.REQUIRED) { consentForm.show( MainActivity.this, new ConsentForm.OnConsentFormDismissedListener() { @Override public void onConsentFormDismissed(@Nullable FormError formError) { // Handle dismissal by reloading form. loadForm(); } }); } } }, new UserMessagingPlatform.OnConsentFormLoadFailureListener() { @Override public void onConsentFormLoadFailure(FormError formError) { // Handle the error. } }); }
Kotlin
private fun loadForm() { UserMessagingPlatform.loadConsentForm( this, { consentForm -> this.consentForm = consentForm if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.REQUIRED) { consentForm.show(this) { formError -> // Handle dismissal by reloading form. loadForm() } } }, { formError -> // Handle the error. } ) }
If consent is not required, you can maintain a reference to the form so that your user can change their consent status.
Testing
Force a geography
The UMP SDK provides a way to test your app's behavior as though the device was
located in the EEA using the
setDebugGeography()
method on
ConsentDebugSettings.Builder
.
You will need to provide your test device's hashed ID in your app's debug
settings to use the debug functionality. If you call
requestConsentInfoUpdate()
without setting this value, your app will log the
required ID hash when run.
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); consentInformation.requestConsentInfoUpdate( this, params, new ConsentInformation.OnConsentInfoUpdateSuccessListener() { @Override public void onConsentInfoUpdateSuccess() { // The consent information state was updated. // You are now ready to check if a form is available. } }, new ConsentInformation.OnConsentInfoUpdateFailureListener() { @Override public void onConsentInfoUpdateFailure(FormError formError) { // Handle the error. } });
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) consentInformation.requestConsentInfoUpdate( this, params, { // The consent information state was updated. // You are now ready to check if a form is available. }, { formError -> // Handle the error. } )
To force the SDK to treat the device as though it is not in the EEA or the UK,
use DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA
. Note that debug settings only work
on test devices. Emulators do not need to be added to the device ID list as they
have testing enabled by default.
Reset consent state
In testing your app with the UMP SDK, you may 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()