Theo Sự đồng ý của người dùng ở Liên minh Châu Âu của Google Chính sách của Google, bạn phải công bố một số thông tin nhất định cho người dùng ở Khu vực kinh tế Châu Âu (EEA) cùng với với Vương quốc Anh và có được sự đồng ý của họ để sử dụng cookie hoặc phương pháp lưu trữ cục bộ khác, trong trường hợp pháp luật yêu cầu và sử dụng dữ liệu cá nhân (chẳng hạn như mã nhận dạng cho quảng cáo) để phân phát quảng cáo. Chính sách này thể hiện các yêu cầu của Chỉ thị về quyền riêng tư và truyền thông điện tử của Liên minh Châu Âu cũng như Quy định chung về việc bảo vệ dữ liệu (GDPR).
Để hỗ trợ các nhà xuất bản đáp ứng các nghĩa vụ của họ theo chính sách này, Google cung cấp SDK Nền tảng thông báo cho người dùng (UMP). SDK UMP đã được cập nhật để hỗ trợ các tiêu chuẩn IAB mới nhất. Giờ đây, tất cả các cấu hình này có thể được được xử lý trong AdMob quyền riêng tư và nhắn tin.
Điều kiện tiên quyết
- Xem hết Hướng dẫn bắt đầu sử dụng
- Android API cấp 21 trở lên (dành cho Android)
- Nếu bạn đang làm việc về các yêu cầu liên quan đến GDPR, hãy đọc bài viết Tác động của các yêu cầu của IAB đến Liên minh Châu Âu thông báo yêu cầu đồng ý
Tạo loại thông báo
Tạo thông báo cho người dùng bằng một trong các loại thông báo cho người dùng hiện có trong Chính sách quyền riêng tư & nhắn tin trong AdMob tài khoản. UMP SDK cố gắng hiển thị thông báo cho người dùng được tạo từ AdMob Mã ứng dụng đã thiết lập trong dự án của bạn. Nếu không có thông báo nào được định cấu hình cho ứng dụng, thì SDK sẽ trả về một lỗi.
Để biết thêm thông tin, hãy xem Giới thiệu về quyền riêng tư và thông báo.
Cài đặt SDK
Làm theo các bước để cài đặt C++ cho Quảng cáo trên thiết bị di động của Google (GMA) SDK. UMP C++ SDK có trong SDK GMA C++.
Hãy đảm bảo rằng bạn định cấu hình ứng dụng AdMob của ứng dụng Mã nhận dạng trong dự án trước khi tiếp tục.
Trong mã của bạn, hãy khởi chạy UMP SDK bằng cách gọi
ConsentInfo::GetInstance()
.- Trên Android, bạn cần chuyển
JNIEnv
vàActivity
do NDK. Bạn chỉ cần thực hiện việc này trong lần đầu tiên gọiGetInstance()
. - Ngoài ra, nếu bạn đã sử dụng Firebase C++
SDK trong ứng dụng của mình, bạn có thể chuyển
trong
firebase::App
vào lần đầu tiên bạn gọiGetInstance()
.
#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
- Trên Android, bạn cần chuyển
Các lệnh gọi tiếp theo của ConsentInfo::GetInstance()
đều trả về cùng một phiên bản.
Nếu đã sử dụng xong UMP SDK, bạn có thể tắt SDK bằng cách xoá
Thực thể ConsentInfo
:
void ShutdownUserMessagingPlatform() {
ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
delete consent_info;
}
Sử dụng Future
để giám sát các hoạt động không đồng bộ
Đáp
firebase::Future
cung cấp cho bạn cách xác định trạng thái hoàn thành của phương thức không đồng bộ
cuộc gọi.
Tất cả các hàm UMP C++ và lệnh gọi phương thức hoạt động không đồng bộ sẽ trả về một
Future
, đồng thời cung cấp "kết quả cuối cùng" để truy xuất Future
từ thao tác gần đây nhất.
Có hai cách để nhận kết quả từ Future
:
- Gọi
OnCompletion()
, truyền vào hàm callback của riêng bạn. Hàm này sẽ được gọi khi hoạt động hoàn tất. - Định kỳ kiểm tra
status()
củaFuture
. Khi trạng thái thay đổi từkFutureStatusPending
thànhkFutureStatusCompleted
, đã hoàn thành thao tác.
Sau khi hoạt động không đồng bộ hoàn tất, bạn nên kiểm tra
error()
của Future
để lấy lỗi của thao tác
. Nếu mã lỗi là 0
(kConsentRequestSuccess
hoặc kConsentFormSuccess
),
hoạt động đã hoàn tất thành công; nếu không, hãy kiểm tra mã lỗi và
error_message()
để xác định xem đã xảy ra sự cố gì.
Lệnh gọi lại khi hoàn thành
Dưới đây là ví dụ về cách sử dụng OnCompletion
để thiết lập một lệnh gọi lại hoàn thành:
được gọi khi hoạt động không đồng bộ hoàn tất.
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.
}
});
}
Cập nhật thăm dò vòng lặp
Trong ví dụ này, sau khi một hoạt động không đồng bộ được bắt đầu khi khởi chạy ứng dụng, kết quả sẽ được kiểm tra ở nơi khác, trong hàm vòng lặp cập nhật của trò chơi (chức năng này chạy một lần cho mỗi khung hình).
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.
}
}
}
}
Để biết thêm thông tin về firebase::Future
, hãy xem SDK C++ của Firebase
tài liệu
và tài liệu về GMA C++.
Thêm mã ứng dụng
Bạn có thể tìm thấy mã ứng dụng của mình trong Giao diện người dùng AdMob. Thêm mã nhận dạng vào bằng đoạn mã sau:
Yêu cầu cung cấp thông tin về sự đồng ý
Bạn nên yêu cầu cập nhật thông tin về sự đồng ý của người dùng ở mọi ứng dụng
chạy, bằng RequestConsentInfoUpdate()
. Điều này xác định
liệu người dùng của bạn có cần phải đồng ý hay không nếu họ chưa đồng ý, hoặc
nếu sự đồng ý của họ đã hết hạn.
#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.
}
});
}
Hãy xem ở trên để biết ví dụ về cách kiểm tra trạng thái hoàn thành bằng cách sử dụng cập nhật vòng lặp thay vì lệnh gọi lại hoàn thành.
Tải và hiển thị biểu mẫu lấy sự đồng ý (nếu cần)
Sau khi bạn nhận được trạng thái đồng ý mới nhất, hãy gọi
LoadAndShowConsentFormIfRequired()
trên
ConsentInfo
để tải biểu mẫu lấy sự đồng ý. Nếu
trạng thái đồng ý là bắt buộc. SDK sẽ tải một biểu mẫu và hiển thị biểu mẫu đó ngay lập tức
từ FormParent
được cung cấp. Future
được hoàn tất sau khi biểu mẫu bị loại bỏ. Nếu không cần phải có sự đồng ý, Future
được hoàn tất ngay lập tức.
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.
}
});
}
});
}
Nếu bạn cần thực hiện bất kỳ hành động nào sau khi người dùng đã đưa ra lựa chọn hoặc bỏ qua
biểu mẫu, hãy đặt logic đó vào mã xử lý Future
được trả về bởi LoadAndShowConsentFormIfRequired()
.
Yêu cầu quảng cáo
Trước khi yêu cầu quảng cáo trong ứng dụng, hãy kiểm tra xem bạn đã nhận được sự đồng ý hay chưa
từ người dùng đang sử dụng ConsentInfo::GetInstance()‑>CanRequestAds()
. Có hai
các địa điểm cần kiểm tra trong quá trình thu thập sự đồng ý:
- Sau khi thu thập được sự đồng ý trong phiên họp hiện tại.
- Ngay sau khi bạn gọi
RequestConsentInfoUpdate()
. Có thể bạn đã nhận được sự đồng ý trong buổi chia sẻ trước. Dưới dạng độ trễ phương pháp hay nhất, chúng tôi khuyên bạn không nên đợi lệnh gọi lại hoàn tất để bạn có thể hãy bắt đầu tải quảng cáo ngay sau khi ứng dụng của bạn khởi chạy.
Nếu xảy ra lỗi trong quá trình thu thập sự đồng ý, bạn vẫn nên cố yêu cầu quảng cáo. UMP SDK sử dụng trạng thái đồng ý từ trước phiên hoạt động.
Ví dụ hoàn chỉnh sau đây sử dụng thăm dò vòng lặp cập nhật, nhưng bạn cũng có thể sử dụng
Các lệnh gọi lại OnCompletion
để giám sát các hoạt động không đồng bộ. Sử dụng
bất kỳ kỹ thuật nào phù hợp hơn với cấu trúc mã của bạn.
#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;
}
}
}
}
Tuỳ chọn quyền riêng tư
Một số biểu mẫu đồng ý yêu cầu người dùng sửa đổi sự đồng ý của họ bất cứ lúc nào. Tuân thủ vào các bước sau đây để triển khai nút tuỳ chọn quyền riêng tư nếu cần.
Để thực hiện điều này:
- Triển khai một thành phần trên giao diện người dùng, chẳng hạn như nút trên trang cài đặt của ứng dụng, có thể kích hoạt biểu mẫu về các lựa chọn về quyền riêng tư.
- Sau khi
LoadAndShowConsentFormIfRequired()
hoàn tất, hãy kiểm tragetPrivacyOptionsRequirementStatus()
để xác định xem có hiển thị hay không thành phần trên giao diện người dùng có thể hiển thị biểu mẫu tuỳ chọn quyền riêng tư. - Khi người dùng tương tác với thành phần trên giao diện người dùng, lệnh gọi
showPrivacyOptionsForm()
hiển thị biểu mẫu để người dùng có thể cập nhật tuỳ chọn bảo mật của họ bất cứ lúc nào.
Thử nghiệm
Nếu bạn muốn kiểm thử việc tích hợp trong ứng dụng khi bạn đang phát triển, hãy làm theo các bước sau để đăng ký thiết bị thử nghiệm của bạn theo phương thức lập trình. Hãy nhớ gỡ bỏ để đặt các mã thiết bị thử nghiệm này trước khi bạn phát hành ứng dụng của mình.
- Gọi
RequestConsentInfoUpdate()
. Kiểm tra đầu ra nhật ký để tìm một thông báo tương tự như ví dụ sau: cho biết mã thiết bị của bạn và cách thêm thiết bị đó làm thiết bị thử nghiệm:
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]
Sao chép mã thiết bị thử nghiệm vào bảng nhớ tạm.
Sửa đổi mã của bạn để đặt
ConsentRequestParameters.debug_settings.debug_device_ids
để danh sách mã thiết bị thử nghiệm của bạn.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); }
Buộc hiển thị một khu vực địa lý
UMP SDK cung cấp một cách để thử nghiệm hành vi của ứng dụng như thể thiết bị
ở Khu vực kinh tế Châu Âu (EEA) hoặc Vương quốc Anh bằng ConsentRequestParameters.debug_settings.debug_geography
. Lưu ý rằng
chế độ cài đặt gỡ lỗi chỉ hoạt động trên thiết bị thử nghiệm.
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);
}
Đặt lại trạng thái đồng ý
Khi thử nghiệm ứng dụng với UMP SDK, bạn có thể thấy hữu ích khi đặt lại
trạng thái của SDK để bạn có thể mô phỏng trải nghiệm cài đặt lần đầu của người dùng.
SDK cung cấp phương thức Reset()
để thực hiện việc này.
ConsentInfo::GetInstance()->Reset();