מתחילים

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

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

  • אם נדרשת הסכמה. לדוגמה, נדרשת הסכמה בפעם הראשונה או שפג התוקף של ההסכמה הקודמת.
  • האם נדרשת נקודת כניסה לאפשרויות הפרטיות. בהודעות פרטיות מסוימות, האפליקציות צריכות לאפשר למשתמשים לשנות את אפשרויות הפרטיות שלהם בכל שלב.
#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());
      }
      // Consent information is successfully updated.
    });
}

טעינת הטופס של הודעת הפרטיות והצגתו

אחרי שתקבלו את סטטוס ההסכמה העדכני ביותר, תוכלו להפעיל את הפונקציה 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() כדי לבדוק אם קיבלתם הסכמה מהמשתמש:

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

  • אחרי ש-UMP SDK אוסף הסכמה בסשן הנוכחי.
  • מיד אחרי שתתקשרו למספר RequestConsentInfoUpdate(). יכול להיות ש-UMP SDK קיבל הסכמה בסשן הקודם של האפליקציה.

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