O SDK da plataforma de mensagens de usuários (UMP) do Google é uma ferramenta de privacidade e mensagens para ajudar você a gerenciar as opções de privacidade. Para mais informações, consulte Sobre a página "Privacidade e mensagens".
Pré-requisitos
- API do Android de nível 21 ou mais recente (para Android)
Criar um tipo de mensagem
Crie mensagens do usuário com um dos tipos disponíveis na guia Privacidade e mensagens da sua conta da AdMob. O SDK da UMP tenta mostrar uma mensagem de privacidade criada com base no ID do aplicativo da AdMob definido no seu projeto.
Para mais detalhes, consulte Sobre privacidade e mensagens.
Instalar o SDK
Siga as etapas para instalar o SDK dos anúncios para dispositivos móveis do Google (GMA) para C++. O SDK do UMP para C++ está incluído no SDK do GMA para C++.
Configure o ID do app AdMob do seu app no projeto antes de continuar.
No código, inicialize o SDK da UMP chamando
ConsentInfo::GetInstance()
.- No Android, é necessário transmitir o
JNIEnv
e oActivity
fornecidos pelo NDK. Você só precisa fazer isso na primeira vez que chamarGetInstance()
. - Como alternativa, se você já estiver usando o SDK do Firebase C++ no seu app, poderá transmitir
um
firebase::App
na primeira vez que chamarGetInstance()
.
#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
- No Android, é necessário transmitir o
As chamadas subsequentes para ConsentInfo::GetInstance()
retornam a mesma instância.
Se você terminar de usar o SDK da UMP, poderá desativá-lo excluindo a
instância ConsentInfo
:
void ShutdownUserMessagingPlatform() {
ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
delete consent_info;
}
Usar um Future
para monitorar operações assíncronas
Um
firebase::Future
oferece uma maneira de determinar o status de conclusão das chamadas de método
assíncronas.
Todas as funções e chamadas de método do UMP em C++ que operam de forma assíncrona retornam um
Future
e também fornecem uma função de "último resultado" para extrair o Future
da operação mais recente.
Há duas maneiras de conseguir um resultado de uma Future
:
- Chame
OnCompletion()
, transmitindo sua própria função de callback, que é chamada quando a operação é concluída. - Verifique periodicamente o
status()
doFuture
. Quando o status mudar dekFutureStatusPending
parakFutureStatusCompleted
, a operação será concluída.
Depois que a operação assíncrona for concluída, verifique o
error()
do Future
para receber o código de erro da operação. Se o código de erro for 0
(kConsentRequestSuccess
ou kConsentFormSuccess
),
a operação foi concluída. Caso contrário, verifique o código de erro e
error_message()
para determinar o que deu errado.
Callback de conclusão
Confira um exemplo de como usar OnCompletion
para definir um callback de conclusão,
que é chamado quando a operação assíncrona é concluída.
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.
}
});
}
Atualizar a pesquisa de loop
Neste exemplo, depois que uma operação assíncrona é iniciada na inicialização do app, os resultados são verificados em outro lugar, na função de loop de atualização do jogo (que é executada uma vez por frame).
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 mais informações sobre firebase::Future
, consulte a documentação do SDK do Firebase para C++
e a documentação do SDK do GMA para C++.
Coletar consentimento
Para coletar o consentimento, siga estas etapas:
- Solicitar as informações mais recentes de consentimento do usuário.
- Carregue e apresente um formulário de consentimento, se necessário.
Solicitação de informações de consentimento
Peça uma atualização das informações de consentimento do usuário em cada inicialização
do app usando
RequestConsentInfoUpdate()
. Essa solicitação verifica
o seguinte:
- Se o consentimento é obrigatório. Por exemplo, o consentimento é necessário pela primeira vez ou a decisão de consentimento anterior expirou.
- Se um ponto de entrada de opções de privacidade é necessário. Algumas mensagens de privacidade exigem que os apps permitam que os usuários modifiquem as opções de privacidade a qualquer momento.
Carregar e apresentar um formulário de mensagem de privacidade, se necessário
Depois de receber o status de consentimento mais atualizado, chame
LoadAndShowConsentFormIfRequired()
para carregar os formulários necessários para
coletar o consentimento do usuário. Após o carregamento, os formulários são apresentados imediatamente.
O código abaixo demonstra como solicitar as informações de consentimento mais recentes do usuário. Se necessário, o código será carregado e apresentará um formulário de mensagem de privacidade:
#include "firebase/gma/ump.h"
namespace ump = ::firebase::gma::ump;
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 privacy message form: %s", form_result.error_message());
} else {
// Either the form was shown and completed by the user, or consent was not required.
}
});
}
});
}
Consulte acima para conferir um exemplo de verificação de conclusão usando a pesquisa de loop de atualização em vez de um callback de conclusão.
Se você precisar realizar ações depois que o usuário fizer uma escolha ou fechar
o formulário, coloque essa lógica no código que processa o Future
retornado por LoadAndShowConsentFormIfRequired()
.
Opções de privacidade
Alguns formulários de mensagem de privacidade são apresentados em um ponto de entrada de opções de privacidade renderizado pelo editor, permitindo que os usuários gerenciem as opções de privacidade a qualquer momento. Para saber mais sobre qual mensagem é exibida aos usuários no ponto de entrada das opções de privacidade, consulte Tipos de mensagem do usuário disponíveis.
Solicitar anúncios
Antes de solicitar anúncios no seu app, verifique se você recebeu o consentimento
do usuário usando
ConsentInfo::GetInstance()‑>
CanRequestAds()
. Há dois
lugares para verificar ao coletar o consentimento:
- Depois que o consentimento foi coletado na sessão atual.
- Imediatamente após chamar
RequestConsentInfoUpdate()
. É possível que o consentimento tenha sido concedido na sessão anterior. Como prática recomendada de latência, recomendamos não esperar a conclusão do callback para que você possa começar a carregar anúncios assim que possível após o lançamento do app.
Se ocorrer um erro durante o processo de coleta de consentimento, ainda será necessário verificar se você pode solicitar anúncios. O SDK do UMP usa o status de consentimento da sessão anterior.
O exemplo completo a seguir usa a pesquisa de loop de atualização, mas você também pode usar
callbacks OnCompletion
para monitorar operações assíncronas. Use
a técnica que melhor se adapta à estrutura do 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 privacy message 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;
}
}
}
}
Teste
Se você quiser testar a integração no seu app durante o desenvolvimento, siga estas etapas para registrar o dispositivo de teste por programação. Remova o código que define esses IDs de dispositivo de teste antes de lançar o app.
- Ligue para a
RequestConsentInfoUpdate()
. Verifique se há uma mensagem semelhante ao exemplo abaixo na saída do registro, que mostra o ID do dispositivo e como adicioná-lo como um dispositivo de teste:
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]
Copie o ID do dispositivo de teste para a área de transferência.
Modifique o código para definir
ConsentRequestParameters.debug_settings.debug_device_ids
como uma lista dos IDs dos dispositivos de teste.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); }
Forçar uma região geográfica
O SDK da UMP oferece uma maneira de testar o comportamento do app como se o dispositivo
estivesse localizado em várias regiões, como o EEE ou o Reino Unido, usando
debug_settings.debug_geography
. As configurações de depuração só funcionam em dispositivos de teste.
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);
}
Redefinir o estado de consentimento
Ao testar seu app com o SDK da UMP, pode ser útil redefinir o
estado do SDK para simular a experiência de instalação de um usuário.
O SDK fornece o método Reset()
para fazer isso.
ConsentInfo::GetInstance()->Reset();