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
- Zapoznaj się z przewodnikiem dla początkujących.
- Interfejs API Androida na poziomie 21 lub wyższym (Android)
- Jeśli pracujesz nad wymaganiami związanymi z RODO, przeczytaj Jak wymagania IAB wpływają na UE wiadomości z prośbą o zgodę na wykorzystanie danych
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
Postępuj zgodnie z instrukcjami, aby zainstalować C++ Reklamy mobilne Google (GMA) SDK. UMP C++ Pakiet SDK jest zawarty w pakiecie GMA C++ SDK.
Upewnij się, że masz skonfigurowaną aplikację AdMob ID w projekcie. zanim przejdziesz dalej.
W swoim kodzie zainicjuj pakiet UMP SDK, wywołując
ConsentInfo::GetInstance()
- Na urządzeniu z Androidem musisz zdać
JNIEnv
iActivity
podane przez NK. Wykonując tę czynność tylko przy pierwszym połączeniu zGetInstance()
. - Jeśli używasz już platformy Firebase C++
pakietu SDK w aplikacji, można przekazać
w
firebase::App
przy pierwszym połączeniu z numeremGetInstance()
.
#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
- Na urządzeniu z Androidem musisz zdać
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:
- Zadzwoń pod numer
OnCompletion()
. przekazującą własną funkcję wywołania zwrotnego, która jest wywoływana, gdy operacja . - Co jakiś czas sprawdzaj:
status()
usługiFuture
. Gdy stan zmiany zkFutureStatusPending
nakFutureStatusCompleted
, 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:
Prośba o informacje dotyczące zgody
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:
- Po uzyskaniu zgody użytkownika w bieżącej sesji.
- 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:
- Zaimplementuj element interfejsu, np. przycisk na stronie ustawień aplikacji, które może wyświetlić formularz opcji prywatności.
- Po
LoadAndShowConsentFormIfRequired()
zakończeniu sprawdź,getPrivacyOptionsRequirementStatus()
, aby określić, czy element interfejsu, który może wyświetlać formularz opcji prywatności. - 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.
- Zadzwoń pod numer
RequestConsentInfoUpdate()
. 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]
Skopiuj identyfikator urządzenia testowego do schowka.
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);
}
Zresetuj stan zgody użytkownika
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();