تحت خطمشی رضایت کاربر اتحادیه اروپا Google، شما باید اطلاعات مشخصی را برای کاربران خود در منطقه اقتصادی اروپا (EEA) همراه با بریتانیا انجام دهید و رضایت آنها را برای استفاده از کوکیها یا سایر فضای ذخیرهسازی محلی، در صورت نیاز قانونی، و استفاده از دادههای شخصی کسب کنید ( مانند AdID) برای ارائه تبلیغات. این سیاست منعکس کننده الزامات دستورالعمل حریم خصوصی الکترونیک اتحادیه اروپا و مقررات عمومی حفاظت از داده ها (GDPR) است.
برای حمایت از ناشران در انجام وظایف خود تحت این خطمشی، Google پلتفرم پیامرسانی کاربر (UMP) SDK را ارائه میدهد. UMP SDK برای پشتیبانی از آخرین استانداردهای IAB به روز شده است. همه این پیکربندیها اکنون میتوانند به راحتی در حریم خصوصی و پیامرسانی AdMob مدیریت شوند.
پیش نیازها
- راهنمای شروع را کامل کنید
- Android API سطح 21 یا بالاتر(برای اندروید)
- اگر روی الزامات مربوط به GDPR کار می کنید،چگونه الزامات IAB بر پیام های رضایت اتحادیه اروپا تأثیر می گذاردالزامات IAB بر پیام های رضایت اتحادیه اروپا تأثیر می گذارد
یک نوع پیام ایجاد کنید
پیامهای کاربری را با یکی از انواع پیام کاربرموجوددر برگه حریم خصوصی و پیامرسانیAdMobManager106 خود ایجاد کنید. UMP SDK سعی می کند یک پیام کاربری ایجاد شده از شناسه برنامه AdMob در پروژه شما نمایش دهد. اگر هیچ پیامی برای برنامه شما پیکربندی نشده باشد، SDK یک خطا برمیگرداند.
برای جزئیات بیشتر،درباره حریم خصوصی و پیامرسانی را ببینید.
SDK را نصب کنید
مراحل نصب Google Mobile Ads (GMA) C++ SDK را دنبال کنید. UMP C++ SDK در GMA C++ SDK گنجانده شده است.
قبل از ادامه، مطمئن شوید که شناسه برنامه AdMob برنامه خود را در پروژه پیکربندی کرده اید.
در کد خود، UMP SDK را با فراخوانی
ConsentInfo::GetInstance()
مقداردهی اولیه کنید.- در Android، باید
JNIEnv
وActivity
ارائه شده توسط NDK را پاس کنید. فقط باید اولین باری کهGetInstance()
را فراخوانی کردید این کار را انجام دهید. - از طرف دیگر، اگر قبلاً از Firebase C++ SDK در برنامه خود استفاده میکنید، میتوانید اولین باری که با
GetInstance()
تماس میگیرید، ازfirebase::App
عبور دهید.
#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
- در Android، باید
فراخوان های بعدی به ConsentInfo::GetInstance()
همگی همان نمونه را برمی گرداند.
اگر استفاده از UMP SDK را تمام کردهاید، میتوانید با حذف نمونه ConsentInfo
، SDK را خاموش کنید:
void ShutdownUserMessagingPlatform() {
ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
delete consent_info;
}
از Future
برای نظارت بر عملیات ناهمزمان استفاده کنید
firebase::Future
راهی برای تعیین وضعیت تکمیل فراخوانی متدهای ناهمزمان در اختیار شما قرار می دهد.
همه توابع UMP C++ و فراخوانیهای متد که به صورت ناهمزمان عمل میکنند، Future
برمیگردانند، و همچنین یک تابع "آخرین نتیجه" را برای بازیابی Future
از آخرین عملیات ارائه میدهند.
دو راه برای به دست آوردن نتیجه از Future
وجود دارد:
- فراخوانی
OnCompletion()
، که تابع callback خودتان را ارسال می کند، که پس از اتمام عملیات فراخوانی می شود. - به صورت دوره ای
status()
Future
را بررسی کنید. وقتی وضعیت ازkFutureStatusPending
بهkFutureStatusCompleted
تغییر کرد، عملیات تکمیل شده است.
پس از اتمام عملیات ناهمزمان، برای دریافت کد خطای عملیات، باید error()
Future
را بررسی کنید. اگر کد خطا 0
باشد ( kConsentRequestSuccess
یا kConsentFormSuccess
)، عملیات با موفقیت انجام شد. در غیر این صورت، کد خطا و error_message()
بررسی کنید تا مشخص شود چه مشکلی رخ داده است.
تکمیل تماس پاسخ
در اینجا مثالی از نحوه استفاده از OnCompletion
برای تنظیم یک فراخوان تکمیلی آورده شده است که پس از اتمام عملیات ناهمزمان فراخوانی می شود.
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.
}
});
}
به روز رسانی حلقه نظرسنجی
در این مثال، پس از شروع یک عملیات ناهمزمان در هنگام راهاندازی برنامه، نتایج در جای دیگری، در تابع حلقه بهروزرسانی بازی (که یک بار در هر فریم اجرا میشود) بررسی میشوند.
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.
}
}
}
}
برای اطلاعات بیشتر درباره firebase::Future
، به مستندات Firebase C++ SDK و مستندات GMA C++ SDK مراجعه کنید.
درخواست اطلاعات رضایت
باید در هر راهاندازی برنامه، با استفاده از RequestConsentInfoUpdate()
درخواست بهروزرسانی اطلاعات رضایت کاربر را بدهید. این تعیین می کند که آیا کاربر شما باید رضایت خود را ارائه دهد، اگر قبلاً این کار را نکرده است یا اینکه رضایت او منقضی شده است.
#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.
}
});
}
برای مثالی از بررسی تکمیل با استفاده از نظرسنجی حلقه به روز رسانی به جای پاسخ به تماس تکمیل ، به بالا مراجعه کنید.
در صورت نیاز فرم رضایت را بارگیری و نمایش دهید
پس از دریافت به روزترین وضعیت رضایت، باLoadAndShowConsentFormIfRequired()
در کلاسConsentInfo
تماس بگیرید تا فرم رضایت بارگیری شود. اگر وضعیت رضایت مورد نیاز باشد، SDK فرمی را بارگیری میکند و بلافاصله آن را از FormParent
ارائه شده ارائه میکند. Future
تکمیل می شود نامیده می شود. اگر رضایت لازم نباشد، Future
تکمیل می شود نامیده می شود.
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.
}
});
}
});
}
اگر بعد از انتخاب کاربر یا رد کردن فرم، نیاز به انجام هر کاری دارید، آن منطق را در کدی قرار دهید که Future
که توسط LoadAndShowConsentFormIfRequired()
بازگردانده شده است قرار دهید.
درخواست تبلیغات
قبل از درخواست تبلیغات در برنامه خود، بررسی کنید که آیا رضایت کاربر را با استفاده از ConsentInfo::GetInstance()‑>CanRequestAds()
دریافت کردهاید. هنگام جمع آوری رضایت دو مکان برای بررسی وجود دارد:
- هنگامی که رضایت در جلسه جاری جمع آوری شد.
- بلافاصله پس از تماس با
RequestConsentInfoUpdate()
. ممکن است در جلسه قبل رضایت گرفته شده باشد. بهعنوان بهترین روش تأخیر، توصیه میکنیم منتظر تکمیل تماس نمانید تا بتوانید در اسرع وقت پس از راهاندازی برنامه، بارگیری تبلیغات را شروع کنید.
اگر در فرآیند جمعآوری رضایت خطایی رخ داد، همچنان باید برای درخواست تبلیغات تلاش کنید. UMP SDK از وضعیت رضایت جلسه قبل استفاده می کند.
مثال کامل زیر از نظرسنجی حلقه به روز رسانی استفاده می کند، اما می توانید از تماس های OnCompletion
برای نظارت بر عملیات ناهمزمان نیز استفاده کنید . از هر تکنیکی که با ساختار کد شما سازگارتر است استفاده کنید.
#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;
}
}
}
}
گزینه های حفظ حریم خصوصی
برخی از فرمهای رضایت از کاربر میخواهند که رضایت خود را در هر زمانی تغییر دهد. برای اجرای دکمه گزینه های حریم خصوصی در صورت لزوم، مراحل زیر را رعایت کنید.
برای انجام این کار:
- یک عنصر رابط کاربری، مانند دکمهای در صفحه تنظیمات برنامهتان، که میتواند فرم گزینههای حریم خصوصی را راهاندازی کند، پیادهسازی کنید.
- هنگامی که
LoadAndShowConsentFormIfRequired()
کامل شد،getPrivacyOptionsRequirementStatus()
را بررسی کنید تا مشخص شود که آیا عنصر UI که می تواند فرم گزینه های حریم خصوصی را ارائه دهد، نمایش داده شود. - هنگامی که کاربر با عنصر UI شما تعامل می کند، با
showPrivacyOptionsForm()
تماس بگیرید تا فرم را نشان دهد تا کاربر بتواند گزینه های حریم خصوصی خود را در هر زمانی به روز کند.
آزمایش کردن
اگر میخواهید یکپارچهسازی را در برنامه خود در حین توسعه آزمایش کنید، این مراحل را دنبال کنید تا دستگاه آزمایشی خود را بصورت برنامهنویسی ثبت کنید. قبل از انتشار برنامه، حتماً کدی را که این شناسههای دستگاه آزمایشی را تنظیم میکند حذف کنید.
- با
RequestConsentInfoUpdate()
تماس بگیرید. خروجی گزارش را برای پیامی شبیه به مثال زیر بررسی کنید، که شناسه دستگاه شما و نحوه افزودن آن را به عنوان یک دستگاه آزمایشی نشان می دهد:
اندروید
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]
شناسه دستگاه آزمایشی خود را در کلیپ بورد خود کپی کنید.
کد خود را به تنظیم کنید
ConsentRequestParameters.debug_settings.debug_device_ids
را به ارسال کنید.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); }
جغرافی اجباری
UMP SDK راهی برای آزمایش رفتار برنامه شما ارائه میکند که گویی دستگاه در منطقه اقتصادی اروپا یا بریتانیا با استفاده از ConsentRequestParameters.debug_settings.debug_geography
قرار دارد. توجه داشته باشید که تنظیمات اشکال زدایی فقط در دستگاه های آزمایشی کار می کند.
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);
}
وضعیت رضایت را بازنشانی کنید
در آزمایش برنامه خود با UMP SDK، ممکن است بازنشانی وضعیت SDK برای شما مفید باشد تا بتوانید اولین تجربه نصب کاربر را شبیه سازی کنید. SDK روش Reset()
برای انجام این کار ارائه می دهد.
ConsentInfo::GetInstance()->Reset();