Get started

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 AdMob privacy & messaging.

Prerequisites

User message types

See User message types for a full list of supported messages. For specific instructions on implementing each message type, see the left navigation bar.

Install with Gradle

If you're using Google Mobile Ads SDK version 19.8.0 or higher, you can skip this Gradle install step. Otherwise, include the UMP SDK in your app's build.gradle as follows:

dependencies {
    // This dependency is automatically included by Google Mobile Ads SDK 19.8.0
    // or higher.
    implementation 'com.google.android.ump:user-messaging-platform:2.0.0'
}

After making the changes to your app's build.gradle, be sure to sync your project with Gradle files.

Update manifest

Next, find your app ID and add it 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">
        <!-- Sample app ID: ca-app-pub-3940256099942544~3347511713 -->
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
        <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>

Determine if a message needs to be displayed

You should request an update of the user's consent information at every app launch, using requestConsentInfoUpdate() before loading a form. This can determine whether or not your user needs to provide consent if they hadn't done so already or if their consent has expired.

Use the information stored in the consentInformation object when you present the form when required.

Here is an example of how to check the status on app start:

Java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

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 under age of consent. false means users are not under
    // age.
    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

package com.example.myapplication

import com.google.android.ump.ConsentForm
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
  private lateinit var consentForm: ConsentForm

  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.
    val params = ConsentRequestParameters
        .Builder()
        .setTagForUnderAgeOfConsent(false)
        .build()

    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        OnConsentInfoUpdateSuccessListener {
          // The consent information state was updated.
          // You are now ready to check if a form is available.
        },
        OnConsentInfoUpdateFailureListener {
          // Handle the error.
        })
  }
}

Load a form if available

Before displaying a form, you first need to determine if one is available. Unavailable forms can be due to the user enabling limited ad tracking or if you’ve tagged them as under the age of consent.

To check the availability of a form, use the isConsentFormAvailable() method on the ConsentInformation instance you created earlier.

Then, add a wrapper method to load the 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,
        OnConsentInfoUpdateSuccessListener {
          // The consent information state was updated.
          // You are now ready to check if a form is available.
          if (consentInformation.isConsentFormAvailable) {
            loadForm()
          }
        },
        OnConsentInfoUpdateFailureListener {
          // Handle the error.
        })
  }

  fun loadForm() {

  }
}

To load the form, use the static loadConsentForm() method on the UserMessagingPlatform class.

Java

public void loadForm() {
  // Loads a consent form. Must be called on the main thread.
  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

fun loadForm() {
  // Loads a consent form. Must be called on the main thread.
  UserMessagingPlatform.loadConsentForm(
      this,
      UserMessagingPlatform.OnConsentFormLoadSuccessListener {
        this.consentForm = consentForm
      },
      UserMessagingPlatform.OnConsentFormLoadFailureListener {
        // Handle the error.
      }
  )
}

Present the form if required

After you’ve determined the form's availability and loaded it, use the show() method on the ConsentForm instance to present the form.

Use the consentInformation object from earlier to check the consent status and update your loadForm() method:

Java

public void loadForm() {
  // Loads a consent form. Must be called on the main thread.
  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) {
                    if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.OBTAINED) {
                      // App can start requesting ads.
                    }

                    // Handle dismissal by reloading form.
                    loadForm();
                  }
            });
          }
        }
      },
      new UserMessagingPlatform.OnConsentFormLoadFailureListener() {
        @Override
        public void onConsentFormLoadFailure(FormError formError) {
          // Handle Error.
        }
      }
  );
}

Kotlin

fun loadForm() {
  // Loads a consent form. Must be called on the main thread.
  UserMessagingPlatform.loadConsentForm(
      this,
      UserMessagingPlatform.OnConsentFormLoadSuccessListener {
        this.consentForm = consentForm
        if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.REQUIRED) {
          consentForm.show(
              this,
              ConsentForm.OnConsentFormDismissedListener {
                if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.OBTAINED) {
                  // App can start requesting ads.
                }

                // Handle dismissal by reloading form.
                loadForm()
              }
          )
        }
      },
      UserMessagingPlatform.OnConsentFormLoadFailureListener {
        // Handle the error.
      }
  )
}

If you need to perform any actions after the user has made a choice or dismissed the form, place that logic in the completion handler or callback for your form.

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 or UK using the setDebugGeography method on ConsentDebugSettings.Builder.

You must 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 logs 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,
        OnConsentInfoUpdateSuccessListener {
          // The consent information state was updated.
          // You are now ready to check if a form is available.
        },
        OnConsentInfoUpdateFailureListener {
          // Handle the error.
        })
}

With the DebugGeography, you have the option to force the geography to one of these options:

DebugGeography Description
DEBUG_GEOGRAPHY_DISABLED Debug geography disabled.
DEBUG_GEOGRAPHY_EEA Geography appears as in EEA for debug devices.
DEBUG_GEOGRAPHY_NOT_EEA Geography appears as not in the EEA for debug devices.

Note that debug settings only work on test devices. Emulators don't need to be added to your device ID list as they already have testing enabled by default.

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()

You should also call reset() if you decide to remove the UMP SDK completely from your project.