אני רוצה לנסות

Google User Messaging Platform (UMP) SDK הוא כלי פרטיות והעברת הודעות שמאפשר עזרה בניהול בחירות הפרטיות. מידע נוסף זמין במאמר הבא: מידע על 'פרטיות' העברת הודעות.

דרישות מוקדמות

  • Android API ברמה 21 ואילך (ל-Android)

איך יוצרים את סוג ההודעה

ליצור הודעות למשתמשים באמצעות אחד הסוגים הזמינים של הודעות למשתמשים בקטע פרטיות העברת הודעות AdMob חשבון. UMP SDK מנסה להציג הודעה בנושא פרטיות שנוצרה מ AdMob מזהה האפליקציה שמוגדרים בפרויקט.

פרטים נוספים זמינים במאמר מידע על הכלי 'פרטיות והודעות'.

התקנת ה-SDK

  1. פועלים לפי השלבים להתקנת Google Mobile Ads (GMA) C++ SDK. UMP C++ SDK כלול ב-GMA C++ SDK.

  2. חשוב להגדיר את אפליקציית AdMob של האפליקציה ID בפרויקט לפני שממשיכים.

  3. בקוד שלך, מאתחלים את UMP SDK על ידי קריאה ConsentInfo::GetInstance()

    • ב-Android, צריך להעביר את השדה JNIEnv ו-Activity שסופקו על ידי ה-NDK. צריך לעשות את זה רק בפעם הראשונה שמתקשרים אל GetInstance().
    • לחלופין, אם אתם כבר משתמשים ב-Firebase C++ ב-SDK באפליקציה, אפשר להעביר בfirebase::App בפעם הראשונה שתתקשרו אל 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
    

הקריאות הבאות שיבוצעו אל ConsentInfo::GetInstance() יחזירו את אותו מופע.

אם סיימתם להשתמש ב-UMP SDK, אפשר לכבות את ה-SDK על ידי מחיקת מופע של ConsentInfo:

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

להשתמש ב-Future למעקב אחרי פעולות אסינכרוניות

א' firebase::Future מספקת דרך לקבוע את סטטוס ההשלמה של השיטה האסינכרונית שיחות.

כל הפונקציות והקריאות לשיטה של UMP C++ שפועלות באופן אסינכרוני מחזירות Future, וגם מספקים את 'התוצאה האחרונה' כדי לאחזר את Future מהפעולה האחרונה.

יש שתי דרכים לקבל תוצאה מ-Future:

  1. קוראים לפונקציה OnCompletion(), להעביר פונקציית קריאה חוזרת (callback), שנקראת כאשר הפעולה שהושלמו.
  2. כדאי לבדוק מדי פעם את status() של Future. כאשר סטטוס משתנה מ-kFutureStatusPending ל-kFutureStatusCompleted, הפעולה הושלמה.

לאחר שהפעולה האסינכרונית תסתיים, עליך לבדוק את מכשיר error() של Future כדי לקבל את שגיאת הפעולה אם קוד השגיאה הוא 0 (kConsentRequestSuccess) או kConsentFormSuccess), הפעולה הושלמה בהצלחה; אחרת, בדקו את קוד השגיאה error_message() כדי לקבוע מה השתבש.

השלמה של קריאה חוזרת

הנה דוגמה לאופן השימוש ב-OnCompletion כדי להגדיר קריאה חוזרת (callback) כהשלמה, נקרא בסיום הפעולה האסינכרונית.

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.

מוסיפים את מזהה האפליקציה

ניתן למצוא את מזהה האפליקציה בקטע ממשק המשתמש של AdMob. מוסיפים את התעודה המזהה עם קטע הקוד הבא:

צריך לבקש עדכון של פרטי ההסכמה של המשתמשים בכל אפליקציה בהפעלה באמצעות 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.
      }
    });
}

למעלה אפשר לראות דוגמה לבדיקת השלמה באמצעות סקרי לולאת עדכון ולא קריאה חוזרת (callback) כהשלמה.

טעינה והצגת טופס הודעה בנושא פרטיות במקרה הצורך

אחרי קבלת סטטוס ההסכמה העדכני ביותר, צריך להתקשר LoadAndShowConsentFormIfRequired() כדי לטעון את כל הטפסים הנדרשים לקבל הסכמה מהמשתמשים. הטפסים מוצגים מיד לאחר הטעינה.

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 privacy message form: %s", form_result.error_message());
          } else {
            // Either the form was shown and completed by the user, or consent was not required.
          }
        });
      }
    });
}

אם אתם צריכים לבצע פעולות כלשהן אחרי שהמשתמש ביצע החלטה או סגר בטופס, ממקמים את הלוגיקה הזו בקוד שמטפל Future הוחזרה על ידי LoadAndShowConsentFormIfRequired().

אפשרויות פרטיות

חלק מהטפסים של הודעות בנושא פרטיות מוצגים מתוך ממשק פרטיות שעבר על ידי בעל התוכן הדיגיטלי נקודת כניסה, כך שמשתמשים יוכלו לנהל את אפשרויות הפרטיות שלהם בכל שלב. למידע נוסף על ההודעה שמוצגת למשתמשים באפשרויות הפרטיות נקודת כניסה, לראות הסוגים הזמינים של הודעות למשתמשים.

כדי להטמיע נקודת כניסה לאפשרויות פרטיות:

  1. צריך לבדוק את getPrivacyOptionsRequirementStatus().
  2. אם נקודת כניסה לאפשרויות פרטיות היא נדרש, יש להוסיף לאפליקציה רכיב גלוי ואינטראקטיבי בממשק המשתמש.
  3. הפעלת טופס אפשרויות הפרטיות באמצעות showPrivacyOptionsForm()

הקוד לדוגמה הבא מדגים את השלבים האלה:

בקשה להצגת מודעות

לפני ששולחים בקשה להצגת מודעות באפליקציה, צריך לבדוק אם קיבלת הסכמה מהמשתמש באמצעות ConsentInfo::GetInstance()‑>CanRequestAds(). יש שתי פלטפורמות מקומות שצריך לבדוק במהלך קבלת ההסכמה:

  • אחרי שהתקבלה הסכמה בסשן הנוכחי.
  • מיד לאחר שהתקשרת אל RequestConsentInfoUpdate(). ייתכן שהתקבלה הסכמה בסשן הקודם. כזמן אחזור מומלץ לא להמתין עד לסיום הקריאה החוזרת כדי שתוכלו להתחיל לטעון מודעות בהקדם האפשרי אחרי השקת האפליקציה.

גם אם תתרחש שגיאה בתהליך קבלת ההסכמה, עדיין עליך מנסים לבקש מודעות. סטטוס ההסכמה מה-UMP SDK הקודם היה סשן.

הדוגמה המלאה הבאה כוללת סקרים לולאה לעדכון, אבל אפשר להשתמש גם בדגימה. OnCompletion קריאות חוזרות (callback) כדי לעקוב אחרי פעולות אסינכרוניות. כדאי להשתמש שמתאימה למבנה הקוד שלכם.

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

בדיקה

כדי לבדוק את השילוב באפליקציה במהלך הפיתוח, צריך לפעול לפי השלבים הבאים: כדי לרשום את מכשיר הבדיקה באופן פרוגרמטי. חשוב להסיר את שמגדיר את מזהי מכשירי הבדיקה האלה לפני השקת האפליקציה.

  1. התקשרות אל RequestConsentInfoUpdate().
  2. בודקים את פלט היומן להודעה שדומה לדוגמה הבאה: מציג את מזהה המכשיר ואיך להוסיף אותו כמכשיר בדיקה:

    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. מעתיקים את מזהה מכשיר הבדיקה ללוח.

  4. יש לשנות את הקוד כדי להגדיר 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 מאפשר לבדוק את התנהגות האפליקציה כאילו המכשיר שנמצאים ב-EEA או בבריטניה דרך 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();

דוגמאות ב-GitHub