Wypróbuj

Obowiązujące w Google zgoda użytkownika z UE , musisz udzielać odpowiednich informacji użytkownikom z Europejskiego Obszaru Gospodarczego (EOG) oraz z Wielką Brytanią i uzyskać ich zgodę na używanie plików cookie lub innych sposobów lokalnego przechowywania informacji, jeśli wymaga tego prawo, oraz wykorzystywać dane osobowe (np. AdID) do wyświetlania reklam. Polityka ta odzwierciedla wymagania UE zawarte w dyrektywie o prywatności i łączności elektronicznej Ogólnego rozporządzenia o ochronie danych (RODO).

Aby pomóc wydawcom w wypełnieniu obowiązków, jakie nakłada na nich ta polityka, Google oferuje pakiet SDK User Messaging Platform (UMP). Pakiet UMP SDK obsługuje teraz zgodne z najnowszymi standardami IAB. Wszystkie te konfiguracje można teraz w wygodny sposób obsługiwane w AdMob ustawieniach prywatności i wysyłanie wiadomości.

Wymagania wstępne

  • Interfejs API Androida na poziomie 21 lub wyższym (Android)

Tworzenie typu wiadomości

Utwórz wiadomości dla użytkowników za pomocą jednej z tych metod: dostępne typy wiadomości dla użytkowników w sekcji Prywatność na karcie „Wiadomości” AdMob koncie. Pakiet UMP SDK próbuje wyświetlić wiadomość dla użytkownika utworzona AdMob na podstawie identyfikatora aplikacji ustawione w projekcie. Jeśli dla aplikacji nie jest skonfigurowany żaden komunikat, pakiet SDK zwraca błąd.

Więcej informacji: Prywatność i wyświetlanie wiadomości

Zainstaluj pakiet SDK

  1. Postępuj zgodnie z instrukcjami, aby zainstalować C++ Reklamy mobilne Google (GMA) SDK. UMP C++ Pakiet SDK jest zawarty w pakiecie GMA C++ SDK.

  2. Upewnij się, że masz skonfigurowaną aplikację AdMob ID w projekcie. zanim przejdziesz dalej.

  3. W swoim kodzie zainicjuj pakiet UMP SDK, wywołując ConsentInfo::GetInstance()

    • Na urządzeniu z Androidem musisz zdać JNIEnv i Activity podane przez NK. Wykonując tę czynność tylko przy pierwszym połączeniu z GetInstance().
    • Jeśli używasz już platformy Firebase C++ pakietu SDK w aplikacji, można przekazać w firebase::App przy pierwszym połączeniu z numerem 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
    

Kolejne wywołania funkcji ConsentInfo::GetInstance() zwracają tę samą instancję.

Jeśli przestaniesz korzystać z pakietu UMP SDK, możesz go wyłączyć, usuwając plik Instancja ConsentInfo:

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

Future do monitorowania operacji asynchronicznych

O firebase::Future pozwala określić stan ukończenia metody asynchronicznej połączeń.

Wszystkie funkcje i wywołania metod UMP w języku C++, które działają asynchronicznie, Future, a także podaj „ostatni wynik” do pobierania funkcji Future od ostatniej operacji.

Wynik z Future można uzyskać na 2 sposoby:

  1. Zadzwoń pod numer OnCompletion(). przekazującą własną funkcję wywołania zwrotnego, która jest wywoływana, gdy operacja .
  2. Co jakiś czas sprawdzaj: status() usługi Future. Gdy stan zmiany z kFutureStatusPending na kFutureStatusCompleted, wartość .

Po zakończeniu operacji asynchronicznej sprawdź error() elementu Future, aby uzyskać błąd operacji w kodzie. Jeśli kod błędu to 0 (kConsentRequestSuccess) lub kConsentFormSuccess), operacja została zakończona pomyślnie; w przeciwnym razie sprawdź kod błędu i error_message(), aby ustalić, co poszło nie tak.

Zakończenie oddzwaniania

Oto przykład użycia funkcji OnCompletion do ustawienia wywołania zwrotnego pełnego połączenia: która jest wywoływana po zakończeniu operacji asynchronicznej.

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

Zaktualizuj odpytywanie w pętli

W tym przykładzie, po rozpoczęciu operacji asynchronicznej przy uruchomieniu aplikacji, funkcja sprawdzanych jest w innym miejscu, w funkcji pętli aktualizacji gry (która działa raz na klatkę).

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

Aby dowiedzieć się więcej o firebase::Future, zapoznaj się z informacjami o pakiecie SDK Firebase C++ dokumentacja oraz dokumentację pakietu SDK do reklam mobilnych Google w C++.

Dodaj identyfikator aplikacji

Identyfikator aplikacji znajdziesz w Interfejs AdMob Dodaj dokument tożsamości do z następującym fragmentem kodu:

Informacje o zgodzie użytkownika należy wysyłać w każdej aplikacji za pomocą funkcji RequestConsentInfoUpdate(). Określa to czy użytkownik musi wyrazić zgodę, jeśli jeszcze tego nie zrobił; czy ich zgoda wygasła.

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

powyżej znajdziesz przykład sprawdzania ukończenia za pomocą odpytywania w pętli aktualizacji, a nie do wywołania zwrotnego zakończenia.

W razie potrzeby wczytaj i wyświetl formularz zgody

Po uzyskaniu najbardziej aktualnego stanu zgody zadzwoń pod numer LoadAndShowConsentFormIfRequired() w ConsentInfo klasy, aby wczytać formularz zgody. Jeśli jest wymagany stan zgody użytkownika, pakiet SDK wczytuje formularz i od razu go wyświetla z podanego FormParent. Future jest wypełniony po zamknięciu formularza. Jeśli zgoda nie jest wymagana, Future jest gotowy natychmiast.

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

Jeśli musisz wykonać jakieś działania po dokonaniu wyboru lub odrzuceniu go przez użytkownika umieść tę logikę w kodzie, który obsługuje Future zwrócone przez: LoadAndShowConsentFormIfRequired().

Wyślij żądanie

Zanim wyślesz prośbę o reklamy w aplikacji, sprawdź, czy masz jej zgodę od użytkownika za pomocą funkcji ConsentInfo::GetInstance()‑>CanRequestAds(). Dostępne są 2 które sprawdzić podczas uzyskiwania zgody użytkowników:

  1. Po uzyskaniu zgody użytkownika w bieżącej sesji.
  2. Zaraz po nawiązaniu połączenia z firmą RequestConsentInfoUpdate(). Możliwe, że w poprzedniej sesji użytkownik wyraził zgodę. Jako opóźnienie zgodnie ze sprawdzoną metodą, nie czekaj na zakończenie połączenia, ponieważ będzie można ładowanie reklam od razu po uruchomieniu aplikacji.

Jeśli w trakcie procesu uzyskiwania zgody użytkowników wystąpi błąd, żądania reklam. Pakiet UMP SDK używa stanu zgody z poprzedniej wersji .

Następujący pełny przykład korzysta z odpytywania w pętlę aktualizacji, ale możesz też użyć OnCompletion wywołania zwrotnego do monitorowania operacji asynchronicznych. Używaj wybierz metodę, która lepiej pasuje do Twojej struktury kodu.

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

Opcje prywatności

Niektóre formularze zgody wymagają od użytkownika zmiany zgody w dowolnym momencie. Stosowanie wykonaj poniższe kroki, by w razie potrzeby zaimplementować przycisk opcji prywatności.

W tym celu:

  1. Zaimplementuj element interfejsu, np. przycisk na stronie ustawień aplikacji, które może wyświetlić formularz opcji prywatności.
  2. Po LoadAndShowConsentFormIfRequired() zakończeniu sprawdź, getPrivacyOptionsRequirementStatus() , aby określić, czy element interfejsu, który może wyświetlać formularz opcji prywatności.
  3. Gdy użytkownik wejdzie w interakcję z elementem interfejsu, wywołaj showPrivacyOptionsForm() aby wyświetlić formularz, aktualizować swoje opcje prywatności w dowolnym momencie.

Testowanie

Jeśli chcesz przetestować integrację w aplikacji w trakcie jej tworzenia, postępuj zgodnie z instrukcjami te kroki, by automatycznie zarejestrować urządzenie testowe. Pamiętaj, aby usunąć który będzie ustawiać te identyfikatory urządzeń testowych przed opublikowaniem aplikacji.

  1. Zadzwoń pod numer RequestConsentInfoUpdate().
  2. Sprawdź, czy w danych wyjściowych dziennika znajduje się komunikat podobny do poniższego przykładu, który pokazuje identyfikator Twojego urządzenia i jak dodać je jako urządzenie testowe:

    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. Skopiuj identyfikator urządzenia testowego do schowka.

  4. Zmodyfikuj swój kod, aby ustawić ConsentRequestParameters.debug_settings.debug_device_ids do listę identyfikatorów urządzeń testowych.

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

Wymuś użycie lokalizacji geograficznej

Pakiet UMP SDK umożliwia przetestowanie działania aplikacji w taki sposób, jakby urządzenie przebywających w Europejskim Obszarze Gospodarczym lub Wielkiej Brytanii za pomocą usługi ConsentRequestParameters.debug_settings.debug_geography. Pamiętaj, że ustawienia debugowania działają tylko na urządzeniach testowych.

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

Podczas testowania aplikacji za pomocą pakietu SDK UMP pomocne może być zresetowanie pliku pakietu SDK, co pozwala symulować pierwszą instalację u użytkownika. Pakiet SDK udostępnia metodę Reset() .

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

Przykłady w GitHubie