תחילת העבודה

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 בפרויקט.

  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 תוכלו לקבוע את סטטוס השלמת הקריאות לשיטות אסינכרוניות.

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

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

  1. קוראים לפונקציה OnCompletion(), שמועברת באמצעות פונקציית קריאה חוזרת (callback) משלכם, שמתרחשת בסיום הפעולה.
  2. כדאי לבדוק מדי פעם את 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.

כדי לאסוף אישורי הסכמה, מבצעים את השלבים הבאים:

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

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

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

אם צריך, טוענים טופס של הודעת פרטיות ומציגים אותו

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

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

#include "firebase/gma/ump.h"

namespace ump = ::firebase::gma::ump;

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

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

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

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

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

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

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

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

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

הדוגמה המלאה הבאה כוללת דגימה של לולאת עדכון, אבל אפשר להשתמש גם בקריאות חוזרות (callbacks) של 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 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 או בריטניה, באמצעות 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);
}

כשבודקים את האפליקציה באמצעות ה-SDK של UMP, כדאי לאפס את המצב של ה-SDK כדי שתוכלו לדמות את חוויית ההתקנה הראשונה של המשתמש. כדי לעשות זאת, ה-SDK מספק את השיטה Reset().

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