Según el Consentimiento de Usuarios de la UE de Google Policy, debes debe divulgar determinada información a los usuarios del Espacio Económico Europeo (EEE) junto con con el Reino Unido y obtener su consentimiento para usar cookies y otro tipo de almacenamiento local. cuando la ley lo requiera, y use datos personales (como el ID del anuncio) para publicar anuncios. Esta política refleja los requisitos de la Directiva de Privacidad Electrónica de la UE y Reglamento General de Protección de Datos (RGPD).
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). Se actualizó el SDK de UMP para que sea compatible con los estándares más recientes de la IAB. Ahora, todas estas configuraciones se pueden manejado en AdMob privacidad y y la mensajería de los datos.
Requisitos previos
- Completa la guía de introducción.
- Nivel de API 21 o versiones posteriores de Android (para Android)
- Si trabaja en requisitos relacionados con el GDPR, lea Cómo afectan los requisitos de la IAB a la UE mensajes de consentimiento
Crea un tipo de mensaje
Crea mensajes de usuario con uno de los tipos de mensajes disponibles para los usuarios en la sección Privacidad y mensajes de tu AdMob de servicio predeterminada. El SDK de UMP intenta mostrar un mensaje de usuario creado a partir del AdMob ID de aplicación establecido en tu proyecto. Si no se configura ningún mensaje para tu aplicación, el SDK devuelve un error.
Para obtener más detalles, consulta Acerca de la privacidad y la mensajería
Cómo instalar el SDK
Sigue los pasos para instalar la aplicación C++ de anuncios de Google para dispositivos móviles (GMA). SDK. El código C++ de UMP El SDK se incluye en el SDK de C++ de GMA.
Asegúrate de configurar la app de AdMob de tu app. ID en el proyecto antes de continuar.
En tu código, inicializa el SDK de UMP llamando
ConsentInfo::GetInstance()
- En Android, debes pasar
JNIEnv
yActivity
que proporciona el NDK. Solo debes hacerlo la primera vez que llames aGetInstance()
. - Como alternativa, si ya usas Firebase C++
SDK en tu app, puedes pasar
en un
firebase::App
la primera vez que llamas aGetInstance()
.
#include "firebase/gma/ump.h" namespace ump = ::firebase::gma::ump; // Initialize using a firebase::App void InitializeUserMessagingPlatform(const firebase::App& app) { ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(app); } // Initialize without a firebase::App #ifdef ANDROID void InitializeUserMessagingPlatform(JNIEnv* jni_env, jobject activity) { ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(jni_env, activity); } #else // non-Android void InitializeUserMessagingPlatform() { ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(); } #endif
- En Android, debes pasar
Las llamadas posteriores a ConsentInfo::GetInstance()
muestran la misma instancia.
Si terminaste de usar el SDK de UMP, puedes cerrarlo borrando el archivo
Instancia ConsentInfo
:
void ShutdownUserMessagingPlatform() {
ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
delete consent_info;
}
Usa un Future
para supervisar operaciones asíncronas.
R
firebase::Future
te proporciona una forma de determinar el estado de finalización del método asíncrono.
llamadas.
Todas las llamadas a métodos y las funciones de UMP C++ que operan de forma asíncrona muestran un
Future
y proporcionar un "último resultado" para recuperar el Future
.
de la operación más reciente.
Existen dos maneras de obtener un resultado de Future
:
- Llamada a
OnCompletion()
, y pasar tu propia función de devolución de llamada, a la que se llama cuando la operación de datos completados. - Verifica periódicamente el
status()
deFuture
. Cuando estado los cambios dekFutureStatusPending
akFutureStatusCompleted
, el la operación se haya completado.
Una vez completada la operación asíncrona, debes verificar el
El error()
de Future
para obtener el error de la operación
código. Si el código de error es 0
(kConsentRequestSuccess
o kConsentFormSuccess
),
la operación se haya completado correctamente; De lo contrario, verifica el código de error y
error_message()
para determinar cuál fue el problema.
Devolución de llamada de finalización
A continuación, se muestra un ejemplo de cómo usar OnCompletion
para configurar una devolución de llamada de finalización.
al que se llama cuando se completa la operación asíncrona.
void MyApplicationStart() {
// [... other app initialization code ...]
ump::ConsentInfo *consent_info = ump::ConsentInfo::GetInstance();
// See the section below for more information about RequestConsentInfoUpdate.
firebase::Future<void> result = consent_info->RequestConsentInfoUpdate(...);
result.OnCompletion([](const firebase::Future<void>& req_result) {
if (req_result.error() == ump::kConsentRequestSuccess) {
// Operation succeeded. You can now call LoadAndShowConsentFormIfRequired().
} else {
// Operation failed. Check req_result.error_message() for more information.
}
});
}
Actualiza el sondeo de bucle
En este ejemplo, después de que se inicia una operación asíncrona cuando se inicia una app, el los resultados se verifican en otro lugar, en la función de bucle de actualización del juego (que ejecuta una vez por fotograma).
ump::ConsentInfo *g_consent_info = nullptr;
bool g_waiting_for_request = false;
void MyApplicationStart() {
// [... other app initialization code ...]
g_consent_info = ump::ConsentInfo::GetInstance();
// See the section below for more information about RequestConsentInfoUpdate.
g_consent_info->RequestConsentInfoUpdate(...);
g_waiting_for_request = true;
}
// Elsewhere, in the game's update loop, which runs once per frame:
void MyGameUpdateLoop() {
// [... other game logic here ...]
if (g_waiting_for_request) {
// Check whether RequestConsentInfoUpdate() has finished.
// Calling "LastResult" returns the Future for the most recent operation.
firebase::Future<void> result =
g_consent_info->RequestConsentInfoUpdateLastResult();
if (result.status() == firebase::kFutureStatusComplete) {
g_waiting_for_request = false;
if (result.error() == ump::kConsentRequestSuccess) {
// Operation succeeded. You can call LoadAndShowConsentFormIfRequired().
} else {
// Operation failed. Check result.error_message() for more information.
}
}
}
}
Para obtener más información sobre firebase::Future
, consulta el SDK de Firebase C++
documentación
y la documentación del SDK de GMA C++.
Agrega el ID de aplicación
Puedes encontrar el ID de la aplicación en la IU de AdMob. Agrega el ID a tu con el siguiente fragmento de código:
Solicitud de información de consentimiento
Debe solicitar una actualización de la información de consentimiento del usuario en cada aplicación
iniciar con RequestConsentInfoUpdate()
. Esto determina
si el usuario debe dar su consentimiento si aún no lo hizo
si venció el consentimiento.
#include "firebase/gma/ump.h"
namespace ump = ::firebase::gma::ump;
void MyApplicationStart() {
ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
// Create a ConsentRequestParameters struct.
ump::ConsentRequestParameters params;
// Set tag for under age of consent. False means users are NOT under age
// of consent.
params.tag_for_under_age_of_consent = false;
consent_info->RequestConsentInfoUpdate(params).OnCompletion(
[](const Future<void>& result) {
if (result.error() != ump::kConsentRequestSuccess) {
LogMessage("Error requesting consent update: %s", result.error_message());
} else {
// Consent status is now available.
}
});
}
Consulte más arriba un ejemplo de cómo verificar la finalización con actualización del sondeo de bucle en lugar de una devolución de llamada de finalización.
Carga y muestra un formulario de consentimiento si es necesario
Una vez que recibas el estado de consentimiento más actualizado, llama
LoadAndShowConsentFormIfRequired()
el
ConsentInfo
para cargar un formulario de consentimiento. Si el botón
el estado de consentimiento es obligatorio, el SDK carga un formulario y lo presenta de inmediato
del FormParent
proporcionado. El Future
se completó después de que se descarta el formulario. Si no se requiere el consentimiento, la Future
se completa de inmediato.
void MyApplicationStart(ump::FormParent parent) {
ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
// Create a ConsentRequestParameters struct..
ump::ConsentRequestParameters params;
// Set tag for under age of consent. False means users are NOT under age of consent.
params.tag_for_under_age_of_consent = false;
consent_info->RequestConsentInfoUpdate(params).OnCompletion(
[*](const Future<void>& req_result) {
if (req_result.error() != ump::kConsentRequestSuccess) {
// req_result.error() is a kConsentRequestError enum.
LogMessage("Error requesting consent update: %s", req_result.error_message());
} else {
consent_info->LoadAndShowConsentFormIfRequired(parent).OnCompletion(
[*](const Future<void>& form_result) {
if (form_result.error() != ump::kConsentFormSuccess) {
// form_result.error() is a kConsentFormError enum.
LogMessage("Error showing consent form: %s", form_result.error_message());
} else {
// Either the form was shown and completed by the user, or consent was not required.
}
});
}
});
}
Si necesitas realizar alguna acción después de que el usuario haya hecho una elección o la descarte
el formulario, coloca esa lógica en el código que controla Future
que devuelve LoadAndShowConsentFormIfRequired()
.
Solicitar anuncios
Antes de solicitar anuncios en tu app, verifica si obtuviste el consentimiento
del usuario con ConsentInfo::GetInstance()‑>CanRequestAds()
. Existen dos
lugares para verificar al obtener el consentimiento:
- Una vez que se obtenga el consentimiento en la sesión actual,
- Inmediatamente después de llamar a
RequestConsentInfoUpdate()
Es posible que se haya obtenido el consentimiento en la sesión anterior. Como una latencia práctica recomendada, te sugerimos que no esperes a que se complete la devolución de llamada para que puedas empezar a cargar anuncios tan pronto como sea posible tras el lanzamiento de tu app.
Si se produce un error durante el proceso de obtención del consentimiento, aún debe de solicitar anuncios. El SDK de UMP usa el estado de consentimiento del anterior sesión.
En el siguiente ejemplo completo, se usa sondeo de bucle de actualización, pero también puedes usar
Devoluciones de llamada OnCompletion
para supervisar operaciones asíncronas. Usa
la técnica que se adapte mejor a la estructura de tu código.
#include "firebase/future.h"
#include "firebase/gma/gma.h"
#include "firebase/gma/ump.h"
namespace gma = ::firebase::gma;
namespace ump = ::firebase::gma::ump;
using firebase::Future;
ump::ConsentInfo* g_consent_info = nullptr;
// State variable for tracking the UMP consent flow.
enum { kStart, kRequest, kLoadAndShow, kInitGma, kFinished, kErrorState } g_state = kStart;
bool g_ads_allowed = false;
void MyApplicationStart() {
g_consent_info = ump::ConsentInfo::GetInstance(...);
// Create a ConsentRequestParameters struct..
ump::ConsentRequestParameters params;
// Set tag for under age of consent. False means users are NOT under age of consent.
params.tag_for_under_age_of_consent = false;
g_consent_info->RequestConsentInfoUpdate(params);
// CanRequestAds() can return a cached value from a previous run immediately.
g_ads_allowed = g_consent_info->CanRequestAds();
g_state = kRequest;
}
// This function runs once per frame.
void MyGameUpdateLoop() {
// [... other game logic here ...]
if (g_state == kRequest) {
Future<void> req_result = g_consent_info->RequestConsentInfoUpdateLastResult();
if (req_result.status() == firebase::kFutureStatusComplete) {
g_ads_allowed = g_consent_info->CanRequestAds();
if (req_result.error() == ump::kConsentRequestSuccess) {
// You must provide the FormParent (Android Activity or iOS UIViewController).
ump::FormParent parent = GetMyFormParent();
g_consent_info->LoadAndShowConsentFormIfRequired(parent);
g_state = kLoadAndShow;
} else {
LogMessage("Error requesting consent status: %s", req_result.error_message());
g_state = kErrorState;
}
}
}
if (g_state == kLoadAndShow) {
Future<void> form_result = g_consent_info->LoadAndShowConsentFormIfRequiredLastResult();
if (form_result.status() == firebase::kFutureStatusComplete) {
g_ads_allowed = g_consent_info->CanRequestAds();
if (form_result.error() == ump::kConsentRequestSuccess) {
if (g_ads_allowed) {
// Initialize GMA. This is another asynchronous operation.
firebase::gma::Initialize();
g_state = kInitGma;
} else {
g_state = kFinished;
}
// Optional: shut down the UMP SDK to save memory.
delete g_consent_info;
g_consent_info = nullptr;
} else {
LogMessage("Error displaying consent form: %s", form_result.error_message());
g_state = kErrorState;
}
}
}
if (g_state == kInitGma && g_ads_allowed) {
Future<gma::AdapterInitializationStatus> gma_future = gma::InitializeLastResult();
if (gma_future.status() == firebase::kFutureStatusComplete) {
if (gma_future.error() == gma::kAdErrorCodeNone) {
g_state = kFinished;
// TODO: Request an ad.
} else {
LogMessage("Error initializing GMA: %s", gma_future.error_message());
g_state = kErrorState;
}
}
}
}
Opciones de privacidad
Algunos formularios de consentimiento requieren que el usuario modifique su consentimiento en cualquier momento. Cumple con los requisitos a los siguientes pasos para implementar un botón de opciones de privacidad si es necesario.
Entonces:
- Implementa un elemento de la IU, como un botón en la página de configuración de tu app. que puede activar un formulario de opciones de privacidad.
- Una vez que se
LoadAndShowConsentFormIfRequired()
complete, revisegetPrivacyOptionsRequirementStatus()
para determinar si se debe mostrar o no el elemento de la IU que puede presentar el formulario de opciones de privacidad. - Cuando un usuario interactúe con tu elemento de la IU, llama
showPrivacyOptionsForm()
para mostrar el formulario a fin de que el usuario pueda actualizar sus opciones de privacidad en cualquier momento.
Prueba
Si quieres probar la integración en tu app mientras desarrollas, sigue estos pasos para registrar tu dispositivo de prueba de manera programática. Asegúrate de quitar código que establece estos IDs de dispositivo de prueba antes de lanzar la app.
- Llama a
RequestConsentInfoUpdate()
. Revisa el resultado del registro para ver si hay un mensaje similar al siguiente ejemplo, que muestra tu ID de dispositivo y cómo agregarlo como dispositivo de prueba:
Android
Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231") to set this as a debug device.
iOS
<UMP SDK>To enable debug mode for this device, set: UMPDebugSettings.testDeviceIdentifiers = @[2077ef9a63d2b398840261c8221a0c9b]
Copia el ID del dispositivo de prueba en el portapapeles.
Modifica tu código para establecido
ConsentRequestParameters.debug_settings.debug_device_ids
para Una lista de los IDs de tus dispositivos de prueba.void MyApplicationStart() { ump::ConsentInfo consent_info = ump::ConsentInfo::GetInstance(...); ump::ConsentRequestParameters params; params.tag_for_under_age_of_consent = false; params.debug_settings.debug_device_ids = {"TEST-DEVICE-HASHED-ID"}; consent_info->RequestConsentInfoUpdate(params); }
Fuerza una ubicación geográfica
El SDK de UMP proporciona una forma de probar el comportamiento de tu app como si el dispositivo no estuviera
ubicados en el EEE o el Reino Unido con ConsentRequestParameters.debug_settings.debug_geography
. Ten en cuenta que
La configuración de depuración solo funciona en dispositivos de prueba.
void MyApplicationStart() {
ump::ConsentInfo consent_info = ump::ConsentInfo::GetInstance(...);
ump::ConsentRequestParameters params;
params.tag_for_under_age_of_consent = false;
params.debug_settings.debug_device_ids = {"TEST-DEVICE-HASHED-ID"};
// Geography appears as EEA for debug devices.
params.debug_settings.debug_geography = ump::kConsentDebugGeographyEEA
consent_info->RequestConsentInfoUpdate(params);
}
Restablecer el estado de consentimiento
Cuando pruebes tu app con el SDK de UMP, puede resultarte útil restablecer
del SDK para que puedas simular
la experiencia de la primera instalación de un usuario.
Para ello, el SDK proporciona el método Reset()
.
ConsentInfo::GetInstance()->Reset();