Começar

O SDK da plataforma de mensagens de usuários (UMP) do Google é uma ferramenta de privacidade e mensagens para ajudar você a gerenciar as escolhas de privacidade. Para mais informações, consulte Sobre privacidade e mensagens.

Pré-requisitos

  • API do Android de nível 21 ou mais recente (para Android)

Criar um tipo de mensagem

Crie mensagens de usuário com um dos Tipos de mensagens para os usuários disponíveis na seção Privacidade e de mensagens do AdMob do Compute Engine. O SDK da UMP tenta exibir uma mensagem de privacidade criada com o AdMob ID do aplicativo é definido no projeto.

Para mais detalhes, consulte Sobre privacidade e mensagens.

Instalar o SDK

  1. Siga as etapas para instalar a versão C++ dos anúncios para dispositivos móveis do Google (GMA) SDK do Cloud. A UMP C++ O SDK está incluído no SDK do GMA para C++.

  2. Configure o app AdMob do seu app. ID no projeto. antes de continuar.

  3. No seu código, inicialize o SDK da UMP chamando ConsentInfo::GetInstance()

    • No Android, você precisa transmitir o JNIEnv e o Activity fornecidos pelo do NDK. Você só precisa fazer isso na primeira vez que chamar GetInstance().
    • Como alternativa, se você já estiver usando a biblioteca Firebase C++ SDK no seu app, é possível transmitir em uma firebase::App na primeira vez que você chamar GetInstance().
    #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
    

As chamadas subsequentes para ConsentInfo::GetInstance() retornam a mesma instância.

Se você terminar de usar o SDK da UMP, desative-o excluindo as Instância de 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 do método assíncrono chamadas.

Todas as chamadas de método e funções C++ da UMP que operam de forma assíncrona retornam um Future e também fornecem um "último resultado" para extrair o Future da operação mais recente.

Há duas maneiras de conferir um resultado de uma Future:

  1. Chame OnCompletion(), passando sua própria função de retorno de chamada, que é chamada quando a operação é concluída.
  2. Verifique o status() do Future periodicamente. Quando o status muda de kFutureStatusPending para kFutureStatusCompleted, a foi concluída.

Após a conclusão da operação assíncrona, você deve verificar o error() do Future para receber o erro da operação o código-fonte. Se o código do erro for 0 (kConsentRequestSuccess ou kConsentFormSuccess), a operação for concluída com sucesso; 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 sondagem de loop

Neste exemplo, depois que uma operação assíncrona é iniciada na inicialização do aplicativo, a os resultados são verificados em outro lugar, na função de loop de atualização do jogo, que executa 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++ documentação e a documentação do SDK do GMA para C++.

Adicionar o ID do aplicativo

Você pode encontrar o ID do aplicativo na interface da AdMob. Adicione o ID pelo seguinte snippet de código:

Solicite uma atualização das informações de consentimento do usuário em todos os apps ao iniciar, usando RequestConsentInfoUpdate(). Essa solicitação verifica o seguinte:

  • Se o consentimento é obrigatório. Por exemplo, o consentimento é necessário para a pela primeira vez ou a decisão de consentimento anterior expirou.
  • Define se um ponto de entrada de opções de privacidade é obrigatório. Algumas mensagens de privacidade exigem que os apps permitam que os usuários modifiquem as opções de privacidade a qualquer momento.
#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.
      }
    });
}

Veja acima um exemplo de verificação de conclusão usando a sondagem de loop de atualização em vez de um callback de conclusão.

Carregue e apresente um formulário de mensagem de privacidade, se necessário

Depois de receber o status de consentimento mais atualizado, ligue LoadAndShowConsentFormIfRequired() para carregar os formulários necessários pedir o consentimento do usuário; Após o carregamento, os formulários são apresentados imediatamente.

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.
          }
        });
      }
    });
}

Se você precisar executar alguma ação depois que o usuário tiver feito uma escolha ou dispensado 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 mensagens de privacidade são apresentados com base em uma política de privacidade renderizada pelo editor. de opções do Google, permitindo que os usuários gerenciem as opções de privacidade a qualquer momento. Para saber mais sobre as mensagens que aparecem para os usuários nas opções de privacidade ponto de entrada, consulte Tipos de mensagens para os usuários disponíveis.

Para implementar um ponto de entrada de opções de privacidade, siga estas etapas:

  1. Verifique getPrivacyOptionsRequirementStatus().
  2. Se um ponto de entrada de opções de privacidade for necessário, adicione um elemento de interface visível e interativo ao seu app.
  3. Acione o formulário de opções de privacidade usando showPrivacyOptionsForm():

O exemplo de código abaixo demonstra essas etapas:

Solicitar anúncios

Antes de solicitar anúncios no seu app, verifique se você recebeu o consentimento do usuário usando ConsentInfo::GetInstance()‑>CanRequestAds(). Existem duas lugares para verificar ao solicitar consentimento:

  • Após o consentimento ser coletado na sessão atual.
  • Imediatamente depois de chamar RequestConsentInfoUpdate(). É possível que o consentimento tenha sido obtido na sessão anterior. Como uma latência prática recomendada, recomendamos não esperar pela conclusão do retorno de chamada para que você possa comece a carregar anúncios o mais rápido possível após o lançamento do seu app.
.

Se ocorrer um erro durante o processo de solicitação de consentimento, ainda será preciso tentar solicitar anúncios. O SDK da UMP usa o status de consentimento dos dados sessão.

O exemplo completo a seguir usa a pesquisa de loop de atualização, mas também é possível usar Callbacks OnCompletion para monitorar operações assíncronas. Usar qualquer técnica que se adapte melhor à sua estrutura de 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 aplicativo durante o desenvolvimento, siga estas etapas para registrar o dispositivo de teste de forma programática. Não se esqueça de remover que define esses IDs de dispositivo de teste antes de lançar o app.

  1. Chame RequestConsentInfoUpdate().
  2. Verifique a saída do registro para encontrar uma mensagem semelhante ao exemplo a seguir, 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]
    
  3. Copie o ID do dispositivo de teste para a área de transferência.

  4. Modifique seu código para set ConsentRequestParameters.debug_settings.debug_device_ids para 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 fosse localizados no EEE ou no Reino Unido usando ConsentRequestParameters.debug_settings.debug_geography. Observe que 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);
}

Ao testar seu app com o SDK da UMP, talvez seja útil redefinir o do SDK para que você possa simular a primeira experiência de instalação de um usuário. O SDK fornece o método Reset() para fazer isso.

  ConsentInfo::GetInstance()->Reset();

Exemplos no GitHub