Jetzt loslegen

Gemäß der Richtlinie zur Einwilligung der Nutzer in der EU von Google müssen Sie Ihren Nutzern im Europäischen Wirtschaftsraum (EWR) und im Vereinigten Königreich bestimmte Informationen offenlegen und ihre Einwilligung zur Verwendung von Cookies oder anderen lokalen Speicherverfahren, sofern gesetzlich erforderlich, sowie zur Verwendung personenbezogener Daten (z. B. AdID) für die Auslieferung von Anzeigen einholen. Die Richtlinie entspricht den Anforderungen der EU-Datenschutzrichtlinie für elektronische Kommunikation und der EU-Datenschutz-Grundverordnung (DSGVO).

Google bietet das User Messaging Platform (UMP) SDK an, um Publisher bei der Umsetzung dieser Richtlinie zu unterstützen. Das UMP SDK wurde aktualisiert, um die neuesten IAB-Standards zu unterstützen. Alle diese Konfigurationen lassen sich jetzt bequem unter AdMob Datenschutz und Mitteilungen verwalten.

Voraussetzungen

  • Android API-Level 21 oder höher (für Android)

Mitteilungstyp erstellen

Erstellen Sie Nutzermitteilungen mit einer der verfügbaren Arten von Nutzermitteilungen auf dem Tab Datenschutz und Mitteilungen in Ihrem AdMob- Konto. Das UMP SDK versucht, eine Nutzernachricht anzuzeigen, die aus der in Ihrem Projekt festgelegten AdMob Anwendungs-ID erstellt wurde. Wenn für Ihre Anwendung keine Nachricht konfiguriert ist, gibt das SDK einen Fehler zurück.

Weitere Informationen finden Sie unter Datenschutz und Mitteilungen.

SDK Installieren

  1. Folgen Sie der Anleitung unter Google Mobile Ads (GMA) C++ SDK installieren. Das UMP C++ SDK ist im GMA C++ SDK enthalten.

  2. Konfigurieren Sie die AdMob-App-ID Ihrer App im Projekt, bevor Sie fortfahren.

  3. Initialisieren Sie in Ihrem Code das UMP SDK, indem Sie ConsentInfo::GetInstance() aufrufen.

    • Unter Android musst du die vom NDK bereitgestellten JNIEnv und Activity übergeben. Das musst du nur tun, wenn du GetInstance() zum ersten Mal aufrufst.
    • Wenn Sie in Ihrer App bereits das Firebase C++ SDK verwenden, können Sie beim ersten Aufruf von GetInstance() auch ein firebase::App übergeben.
    #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
    

Die nachfolgenden Aufrufe von ConsentInfo::GetInstance() geben alle dieselbe Instanz zurück.

Wenn Sie das UMP SDK nicht mehr verwenden, können Sie es beenden, indem Sie die Instanz ConsentInfo löschen:

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

Future verwenden, um asynchrone Vorgänge zu überwachen

Mit firebase::Future können Sie den Abschlussstatus asynchroner Methodenaufrufe ermitteln.

Alle UMP C++-Funktionen und -Methodenaufrufe, die asynchron ausgeführt werden, geben ein Future zurück und bieten auch eine Funktion für das letzte Ergebnis, um die Future des letzten Vorgangs abzurufen.

Es gibt zwei Möglichkeiten, ein Ergebnis von einem Future zu erhalten:

  1. Rufen Sie OnCompletion() auf und übergeben Sie Ihre eigene Callback-Funktion, die nach Abschluss des Vorgangs aufgerufen wird.
  2. Prüfe regelmäßig die status() des Future. Wenn sich der status von kFutureStatusPending zu kFutureStatusCompleted ändert, ist der Vorgang abgeschlossen.

Nach Abschluss des asynchronen Vorgangs sollten Sie den error() von Future prüfen, um den Fehlercode des Vorgangs abzurufen. Wenn der Fehlercode 0 (kConsentRequestSuccess oder kConsentFormSuccess) lautet, wurde der Vorgang erfolgreich abgeschlossen. Prüfen Sie andernfalls den Fehlercode und error_message(), um festzustellen, was schiefgelaufen ist.

Callback für Abschluss

Das folgende Beispiel zeigt, wie Sie mit OnCompletion einen Abschluss-Callback festlegen, der nach Abschluss des asynchronen Vorgangs aufgerufen wird.

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

Schleifenabfrage aktualisieren

In diesem Beispiel werden die Ergebnisse an anderer Stelle in der Aktualisierungsschleife des Spiels überprüft, nachdem beim Start der App ein asynchroner Vorgang gestartet wurde. Die Funktion wird einmal pro Frame ausgeführt.

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

Weitere Informationen zu firebase::Future finden Sie in der Dokumentation zum Firebase C++ SDK und in der Dokumentation zum GMA C++ SDK.

Du solltest die Einwilligungsinformationen des Nutzers bei jedem Start einer App mit RequestConsentInfoUpdate()aktualisieren. So wird festgelegt, ob Nutzer ihre Einwilligung geben müssen, falls sie dies noch nicht getan haben, oder ob die Einwilligung abgelaufen ist.

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

Oben finden Sie ein Beispiel für eine abgeschlossene Prüfung mithilfe von Updateschleifen-Polling statt eines Abschluss-Callbacks.

Einwilligungsformular laden und bei Bedarf anzeigen

Nachdem Sie den aktuellen Einwilligungsstatus erhalten haben, rufen SieLoadAndShowConsentFormIfRequired() in der KlasseConsentInfo auf, um ein Einwilligungsformular zu laden. Wenn der Einwilligungsstatus erforderlich ist, wird vom SDK ein Formular geladen und sofort aus dem bereitgestellten FormParentangezeigt. Der Future ist abgeschlossen , nachdem das Formular geschlossen wurde. Ist keine Einwilligung erforderlich, wird die Future abgeschlossen sofort aufgerufen.

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

Wenn Sie Aktionen ausführen müssen, nachdem der Nutzer eine Auswahl getroffen oder das Formular geschlossen hat, fügen Sie diese Logik in den Code ein, der das von LoadAndShowConsentFormIfRequired() zurückgegebene Future verarbeitet.

Anzeigenanfrage senden

Bevor Sie Anzeigen in Ihrer App anfordern, prüfen Sie, ob Sie über ConsentInfo::GetInstance()‑>CanRequestAds()die Einwilligung des Nutzers eingeholt haben. Es gibt zwei Stellen, an denen Sie die Einwilligung einholen müssen:

  1. Sobald in der aktuellen Sitzung die Einwilligung eingeholt wurde.
  2. Sofort nach dem Anruf bei RequestConsentInfoUpdate(). Möglicherweise wurde in der vorherigen Sitzung eine Einwilligung eingeholt. Als Best Practice für die Latenz empfehlen wir, nicht auf den Abschluss des Callbacks zu warten, damit Sie so schnell wie möglich nach dem Start Ihrer App mit dem Laden der Anzeigen beginnen können.
aufgerufen haben.

Falls beim Einholen der Einwilligung ein Fehler auftritt, sollten Sie trotzdem versuchen, Anzeigen anzufordern. Das UMP SDK verwendet den Einwilligungsstatus aus der vorherigen Sitzung.

Im folgenden vollständigen Beispiel werden Updateschleifen abgefragt. Sie können aber auch OnCompletion-Callbacks verwenden, um asynchrone Vorgänge zu überwachen. Verwenden Sie die Methode, die am besten zu Ihrer Codestruktur passt.

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

Datenschutzoptionen

Bei einigen Einwilligungsformularen muss der Nutzer seine Einwilligung jederzeit ändern. Führen Sie bei Bedarf die folgenden Schritte aus, um eine Schaltfläche für Datenschutzoptionen zu implementieren.

Folgende Schritte sind hierzu nötig:

  1. Implementieren Sie ein UI-Element, z. B. eine Schaltfläche auf der Einstellungsseite Ihrer App, über die ein Formular mit Datenschutzoptionen aufgerufen werden kann.
  2. Wenn der LoadAndShowConsentFormIfRequired() -Vorgang abgeschlossen ist, klicken Sie aufgetPrivacyOptionsRequirementStatus() , um zu bestimmen, ob das UI-Element angezeigt werden soll, das das Formular für Datenschutzoptionen anzeigen kann.
  3. Wenn ein Nutzer mit Ihrem UI-Element interagiert, rufen SieshowPrivacyOptionsForm() auf, um das Formular aufzurufen. So kann der Nutzer seine Datenschutzoptionen jederzeit aktualisieren.

Testen

Wenn du die Integration in deiner App während der Entwicklung testen möchtest, führe die folgenden Schritte aus, um dein Testgerät programmatisch zu registrieren.

  1. Rufen Sie RequestConsentInfoUpdate()an.
  2. Suchen Sie in der Logausgabe nach einer Nachricht, die in etwa so aussieht:

    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. Kopiere die Testgeräte-ID in die Zwischenablage.

  4. Ändern Sie den Code so, dassset ConsentRequestParameters.debug_settings.debug_device_ids auf eine Liste Ihrer Testgeräte-IDs übergeben wird.

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

Region erzwingen

Mit dem UMP SDK können Sie mithilfe von ConsentRequestParameters.debug_settings.debug_geographydas Verhalten Ihrer App so testen, als befände sich das Gerät im EWR oder im Vereinigten Königreich. Die Einstellungen für die Fehlerbehebung funktionieren nur auf Testgeräten.

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

Beim Testen Ihrer App mit dem UMP SDK kann es hilfreich sein, den SDK-Status zurückzusetzen, damit Sie die erste Installation eines Nutzers simulieren können. Das SDK bietet dazu die Methode Reset() .

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