Premiers pas

Le SDK Google UMP (User Messaging Platform) est un outil de confidentialité et de messagerie qui vous aide à gérer les choix de confidentialité. Pour en savoir plus, consultez la section À propos de "Confidentialité et messages".

Prérequis

  • Niveau d'API Android 21 ou version ultérieure (pour Android)

Créer un type de message

Créez des messages destinés aux utilisateurs avec l'un des types de messages disponibles dans l'onglet Confidentialité et messages de votre compte AdMob. Le SDK UMP tente d'afficher un message de confidentialité créé à partir de l'ID d'application AdMob défini dans votre projet.

Pour en savoir plus, consultez À propos de la confidentialité et des messages.

Installer le SDK

  1. Suivez la procédure pour installer le SDK Google Mobile Ads (GMA) C++. Le SDK UMP C++ est inclus dans le SDK GMA C++.

  2. Assurez-vous de configurer l'ID de l'application AdMob de votre application dans le projet avant de continuer.

  3. Dans votre code, initialisez le SDK UMP en appelant ConsentInfo::GetInstance().

    • Sur Android, vous devez transmettre les JNIEnv et Activity fournis par le NDK. Vous n'avez besoin de le faire que la première fois que vous appelez GetInstance().
    • Si vous utilisez déjà le SDK Firebase C++ dans votre application, vous pouvez également transmettre un firebase::App la première fois que vous appelez 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
    

Les appels ultérieurs à ConsentInfo::GetInstance() renvoient tous la même instance.

Si vous avez terminé d'utiliser le SDK UMP, vous pouvez l'arrêter en supprimant l'instance ConsentInfo :

void ShutdownUserMessagingPlatform() {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
  delete consent_info;
}

Utiliser un Future pour surveiller les opérations asynchrones

Un firebase::Future vous permet de déterminer l'état d'avancement des appels de méthode asynchrones.

Toutes les fonctions et les appels de méthode UMP C++ qui fonctionnent de manière asynchrone renvoient un Future et fournissent également une fonction "dernier résultat" pour récupérer le Future de l'opération la plus récente.

Il existe deux façons d'obtenir un résultat à partir d'un Future :

  1. Appelez OnCompletion() en transmettant votre propre fonction de rappel, qui est appelée une fois l'opération terminée.
  2. Vérifiez régulièrement l'status() de l'Future. Lorsque l'état passe de kFutureStatusPending à kFutureStatusCompleted, l'opération est terminée.

Une fois l'opération asynchrone terminée, vous devez vérifier le error() de Future pour obtenir le code d'erreur de l'opération. Si le code d'erreur est 0 (kConsentRequestSuccess ou kConsentFormSuccess), l'opération a bien abouti. Dans le cas contraire, vérifiez le code d'erreur et error_message() pour déterminer le problème.

Rappel de fin

Voici un exemple d'utilisation de OnCompletion pour définir un rappel de fin, appelé à la fin de l'opération asynchrone.

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

Mettre à jour l'interrogation de la boucle

Dans cet exemple, une fois qu'une opération asynchrone est lancée au démarrage de l'application, les résultats sont vérifiés ailleurs, dans la fonction de boucle de mise à jour du jeu (qui s'exécute une fois par 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.
      }
    }
  }
}

Pour en savoir plus sur firebase::Future, consultez la documentation du SDK Firebase C++ et la documentation du SDK GMA C++.

Pour recueillir le consentement, procédez comme suit :

  1. Demande des informations sur le consentement de l'utilisateur les plus récentes.
  2. Chargez et présentez un formulaire de consentement, si nécessaire.

Vous devez demander la mise à jour des informations sur le consentement de l'utilisateur à chaque lancement de l'application, à l'aide de RequestConsentInfoUpdate(). Cette requête vérifie les éléments suivants :

  • Indique si le consentement est requis. Par exemple, le consentement est requis pour la première fois, ou la décision précédente concernant le consentement a expiré.
  • Indique si un point d'entrée pour les options de confidentialité est obligatoire. Certains messages de confidentialité exigent que les applications permettent aux utilisateurs de modifier leurs options de confidentialité à tout moment.

Charger et présenter un formulaire de message de confidentialité si nécessaire

Une fois que vous avez reçu l'état de consentement le plus récent, appelez LoadAndShowConsentFormIfRequired() pour charger les formulaires requis pour recueillir le consentement de l'utilisateur. Une fois le chargement terminé, les formulaires s'affichent immédiatement.

Le code suivant montre comment demander les dernières informations sur le consentement de l'utilisateur. Si nécessaire, le code charge et présente un formulaire de message de confidentialité :

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

Consultez ci-dessus pour obtenir un exemple de vérification de l'achèvement à l'aide d'une requête de boucle de mise à jour plutôt qu'un rappel de fin.

Si vous devez effectuer des actions après que l'utilisateur a fait un choix ou fermé le formulaire, placez cette logique dans le code qui gère le Future renvoyé par LoadAndShowConsentFormIfRequired().

Options de confidentialité

Certains formulaires de message sur la confidentialité sont présentés à partir d'un point d'entrée des options de confidentialité affiché par l'éditeur, ce qui permet aux utilisateurs de gérer leurs options de confidentialité à tout moment. Pour en savoir plus sur le message que vos utilisateurs voient au point d'entrée des options de confidentialité, consultez la section Types de messages utilisateur disponibles.

Demander des annonces

Avant de demander des annonces dans votre application, vérifiez si vous avez obtenu le consentement de l'utilisateur à l'aide de ConsentInfo::GetInstance()‑> CanRequestAds(). Il existe deux endroits où vérifier le consentement lors de la collecte :

  • Une fois que le consentement a été obtenu lors de la session en cours.
  • Immédiatement après avoir appelé RequestConsentInfoUpdate(). Il est possible que le consentement ait été obtenu lors de la session précédente. En règle générale, nous vous recommandons de ne pas attendre la fin du rappel afin de pouvoir commencer à charger les annonces dès que possible après le lancement de votre application.

Si une erreur se produit lors du processus de collecte du consentement, vous devez quand même vérifier si vous pouvez demander des annonces. Le SDK UMP utilise l'état du consentement de la session précédente.

L'exemple complet suivant utilise l'interrogation de la boucle de mise à jour, mais vous pouvez également utiliser des rappels OnCompletion pour surveiller les opérations asynchrones. Utilisez la technique qui convient le mieux à la structure de votre code.

#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;
      }
    }
  }
}

Tests

Si vous souhaitez tester l'intégration dans votre application pendant le développement, suivez ces étapes pour enregistrer votre appareil de test par programmation. Veillez à supprimer le code qui définit ces ID d'appareil de test avant de publier votre application.

  1. Appelez RequestConsentInfoUpdate().
  2. Dans la sortie du journal, recherchez un message semblable à l'exemple suivant, qui montre l'ID de votre appareil et explique comment l'ajouter en tant qu'appareil de test:

    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. Copiez l'ID de votre appareil de test dans le presse-papiers.

  4. Modifiez votre code pour définir ConsentRequestParameters.debug_settings.debug_device_ids sur une liste de vos ID d'appareils de test.

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

Forcer une zone géographique

Le SDK UMP permet de tester le comportement de votre application comme si l'appareil était situé dans différentes régions, telles que l'EEE ou le Royaume-Uni, à l'aide de debug_settings.debug_geography. Notez que les paramètres de débogage ne fonctionnent que sur les appareils de test.

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

Lorsque vous testez votre application avec le SDK UMP, il peut être utile de réinitialiser l'état du SDK afin de pouvoir simuler la première expérience d'installation d'un utilisateur. Pour ce faire, le SDK fournit la méthode Reset().

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