Cómo comenzar

Según la Política de Consentimiento de Usuarios de la UE de Google, debes divulgar cierta información a los usuarios del Espacio Económico Europeo (EEE) y el Reino Unido, y obtener su consentimiento para usar cookies y otro tipo de almacenamiento local (cuando sea un requisito legal) y utilizar datos personales (como el ID del anuncio) para publicar anuncios. Esta política refleja los requisitos de la Directiva de Privacidad Electrónica y el Reglamento General de Protección de Datos (GDPR) de la UE.

Para ayudar a los publicadores a cumplir con sus obligaciones en virtud de esta política, Google ofrece el SDK de User Messaging Platform (UMP). El SDK de UMP se actualizó para ser compatible con los estándares más recientes de IAB. Ahora todas estas configuraciones se pueden manejar de forma conveniente en AdMob privacidad y mensajería.

Requisitos previos

  • Nivel de API 21 o posterior de Android

Cómo crear un tipo de mensaje

Crea mensajes para el usuario con uno de los tipos de mensajes para el usuario disponibles en la pestaña Privacidad y mensajería de tu cuenta de AdMob . El SDK de UMP intenta mostrar un mensaje para el usuario creado a partir del AdMob ID de aplicación configurado en tu proyecto. Si no se configura ningún mensaje para tu aplicación, el SDK muestra un error.

Para obtener más detalles, consulta Acerca de la privacidad y la mensajería.

Cómo instalar con Gradle

Agrega la dependencia para el SDK de Google User Messaging Platform al archivo Gradle de nivel de app de tu módulo, que suele ser app/build.gradle:

dependencies {
  implementation("com.google.android.ump:user-messaging-platform:2.1.0")
}

Después de realizar los cambios en el archivo build.gradle de tu app, asegúrate de sincronizar tu proyecto con los archivos de Gradle.

Debes solicitar una actualización de la información de consentimiento del usuario en cada lanzamiento de la app mediante requestConsentInfoUpdate(). Esto determina si el usuario debe dar su consentimiento si aún no lo hizo o si venció.

A continuación, se muestra un ejemplo de cómo verificar el estado de MainActivity en el método onCreate().

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

Cargar y mostrar un formulario de consentimiento si es necesario

Importante: Las siguientes APIs son compatibles con el SDK de UMP 2.1.0 o versiones posteriores.

Una vez que recibas el estado de consentimiento más actualizado, llama aloadAndShowConsentFormIfRequired() en la claseConsentForm para cargar un formulario de consentimiento. Si el estado de consentimiento es obligatorio, el SDK carga un formulario y lo presenta de inmediato desde el activityproporcionado. callback se invoca después de que se descarta el formulario. Si no se requiere el consentimiento, callback se llama de inmediato.

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

Si necesitas realizar acciones después de que el usuario haya elegido o descartado el formulario, coloca esa lógica en el archivo callbackde tu formulario.

Solicitar anuncios

Antes de solicitar anuncios en tu app, verifica si obtuviste el consentimiento del usuario mediante canRequestAds(). Hay dos lugares que debes verificar cuando obtienes el consentimiento:

  1. Una vez que se haya recopilado el consentimiento de la sesión actual.
  2. Inmediatamente después de llamar a requestConsentInfoUpdate(). Es posible que se haya obtenido el consentimiento en la sesión anterior. Como práctica recomendada para la latencia, sugerimos no esperar a que se complete la devolución de llamada para que puedas comenzar a cargar anuncios lo antes posible después de que se inicie la app.
.

Si se produce un error durante el proceso de obtención de consentimiento, aún debes intentar solicitar anuncios. El SDK de UMP usa el estado de consentimiento de la sesión anterior.

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.getAndSet(true)) {
      return
    }

    // Initialize the Google Mobile Ads SDK.
    MobileAds.initialize(this)

    // TODO: Request an ad.
    // InterstitialAd.load(...)
  }
}

Opciones de privacidad

Algunos formularios de consentimiento requieren que el usuario modifique su consentimiento en cualquier momento. Sigue los pasos que se indican a continuación para implementar un botón de opciones de privacidad si es necesario.

Entonces:

  1. Implementa un elemento de la IU, como un botón en la página de configuración de la app, que pueda activar un formulario de opciones de privacidad.
  2. Una vez que se complete loadAndShowConsentFormIfRequired() , marcaprivacyOptionsRequirementStatus() para determinar si se muestra el elemento de la IU que puede presentar el formulario de opciones de privacidad.
  3. Cuando un usuario interactúe con tu elemento de la IU, llama ashowPrivacyOptionsForm() para mostrar el formulario de modo que el usuario pueda actualizar sus opciones de privacidad en cualquier momento.

En el siguiente ejemplo, se muestra cómo presentar el formulario de opciones de privacidad de un MenuItem.

Java

private final ConsentInformation consentInformation;

// Show a privacy options button if required.
public boolean isPrivacyOptionsRequired() {
  return consentInformation.getPrivacyOptionsRequirementStatus()
      == PrivacyOptionsRequirementStatus.REQUIRED;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
  // ...

  consentInformation = UserMessagingPlatform.getConsentInformation(this);
  consentInformation.requestConsentInfoUpdate(
      this,
      params,
      (OnConsentInfoUpdateSuccessListener) () -> {
        UserMessagingPlatform.loadAndShowConsentFormIfRequired(
          this,
          (OnConsentFormDismissedListener) loadAndShowError -> {
            // ...

            // Consent has been gathered.

            if (isPrivacyOptionsRequired()) {
              // Regenerate the options menu to include a privacy setting.
              invalidateOptionsMenu();
            }
          }
        )
      }
      // ...
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.action_menu, menu);
  MenuItem moreMenu = menu.findItem(R.id.action_more);
  moreMenu.setVisible(isPrivacyOptionsRequired());
  return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
  // ...

  popup.setOnMenuItemClickListener(
      popupMenuItem -> {
        if (popupMenuItem.getItemId() == R.id.privacy_settings) {
          // Present the privacy options form when a user interacts with
          // the privacy settings button.
          UserMessagingPlatform.showPrivacyOptionsForm(
              this,
              formError -> {
                if (formError != null) {
                  // Handle the error.
                }
              }
          );
          return true;
        }
        return false;
      });
  return super.onOptionsItemSelected(item);
}

Kotlin

private val consentInformation: ConsentInformation =
  UserMessagingPlatform.getConsentInformation(context)

// Show a privacy options button if required.
val isPrivacyOptionsRequired: Boolean
  get() =
    consentInformation.privacyOptionsRequirementStatus ==
      ConsentInformation.PrivacyOptionsRequirementStatus.REQUIRED

override fun onCreate(savedInstanceState: Bundle?) {
  ...
  consentInformation = UserMessagingPlatform.getConsentInformation(this)
  consentInformation.requestConsentInfoUpdate(
      this,
      params,
      ConsentInformation.OnConsentInfoUpdateSuccessListener {
        UserMessagingPlatform.loadAndShowConsentFormIfRequired(
          this@MainActivity,
          ConsentForm.OnConsentFormDismissedListener {
            // ...

            // Consent has been gathered.

            if (isPrivacyOptionsRequired) {
              // Regenerate the options menu to include a privacy setting.
              invalidateOptionsMenu();
            }
          }
        )
      }
      // ...
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
  menuInflater.inflate(R.menu.action_menu, menu)
  menu?.findItem(R.id.action_more)?.apply {
    isVisible = isPrivacyOptionsRequired
  }
  return super.onCreateOptionsMenu(menu)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
  // ...

  popup.setOnMenuItemClickListener { popupMenuItem ->
    when (popupMenuItem.itemId) {
      R.id.privacy_settings -> {
        // Present the privacy options form when a user interacts with
        // the privacy settings button.
        UserMessagingPlatform.showPrivacyOptionsForm(this) { formError ->
          formError?.let {
            // Handle the error.
          }
        }
        true
      }
      else -> false
    }
  }
  return super.onOptionsItemSelected(item)
}

Prueba

Si quieres probar la integración en tu app mientras desarrollas, sigue los pasos que se indican a continuación para registrar tu dispositivo de prueba de manera programática.

  1. Llama a requestConsentInfoUpdate().
  2. Busca el resultado del registro para ver un mensaje similar al que se muestra a continuación, en el que se muestra el ID de tu dispositivo y cómo agregarlo como un dispositivo de prueba:

    Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231") to set this as a debug device.
    
  3. Copia el ID de tu dispositivo de prueba en el portapapeles.

  4. Modifica tu código para llamar ConsentDebugSettings.Builder().addTestDeviceHashedId() y pasar una lista de los IDs de tus dispositivos de prueba.

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,
    ...
)

Cómo forzar una ubicación geográfica

El SDK de UMP proporciona una forma de probar el comportamiento de tu app como si el dispositivo estuviera ubicado en el EEE o el Reino Unido mediante the setDebugGeography() method which takes a DebugGeography on ConsentDebugSettings.Builder. Ten en cuenta que la configuración de depuración solo funciona en dispositivos de prueba.

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,
    ...
)

Cuando pruebes tu app con el SDK de UMP, tal vez te resulte útil restablecer el estado del SDK para que puedas simular la experiencia de la primera instalación de un usuario. El SDK proporciona el método reset() para hacerlo.

Java

consentInformation.reset();

Kotlin

consentInformation.reset()

Ejemplos en GitHub

Ejemplos de integración del SDK de UMP: Java | Kotlin