البدء

حزمة تطوير البرامج (SDK) لمنصّة Google User Messaging Platform هي أداة خصوصية ومراسلة تساعدك في إدارة خيارات الخصوصية. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة لمحة عن "الخصوصية والمراسلة".

المتطلبات الأساسية

  • المستوى 21 أو إصدار أحدث لواجهة برمجة التطبيقات Android (لأجهزة Android)

إنشاء نوع رسالة

أنشئ رسائل مستخدمين باستخدام أحد أنواع رسائل المستخدمين المتاحة ضمن علامة التبويب الخصوصية والمراسلة في حسابك على AdMob. تحاول حزمة تطوير البرامج لمنصّة UMP عرض رسالة خصوصية تم إنشاؤها من معرّف تطبيق AdMob الذي تم ضبطه في مشروعك.

لمزيد من التفاصيل، يُرجى الاطّلاع على لمحة عن الخصوصية والرسائل.

تثبيت حزمة تطوير البرامج (SDK)

  1. اتّبِع الخطوات لتثبيت "SDK لإعلانات Google على الأجهزة الجوّالة" (GMA) الخاصة بتطبيقات C++‎. يتم تضمين حزمة تطوير البرامج (SDK) لمنصّة UMP ‏(بتنسيق C++) في حزمة تطوير البرامج (SDK) لمنصّة "إعلانات Google على الأجهزة الجوّالة" (بتنسيق C++).

  2. تأكَّد من ضبط ملف تعريف AdMob للتطبيق في المشروع قبل المتابعة.

  3. في الرمز البرمجي، ابدأ إعداد حزمة تطوير البرامج (SDK) لمنصّة UMP من خلال استدعاء ConsentInfo::GetInstance().

    • على نظام التشغيل Android، عليك ضبط JNIEnv وActivity المقدَّمين من IDE. ولن تحتاج إلى إجراء ذلك إلا في المرة الأولى التي تتصل فيها بـ GetInstance().
    • بدلاً من ذلك، إذا كنت تستخدم حزمة تطوير البرامج (SDK) لنظام firebase::App Firebase C++ في تطبيقك، يمكنك تمرير 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() المثيل نفسه.

إذا كنت قد انتهيت من استخدام حزمة SDK لمنصّة UMP، يمكنك إيقاف حزمة SDK عن طريق حذف مثيل ConsentInfo:

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

استخدام Future لمراقبة العمليات غير المتزامنة

يوفّر لك الرمز البرمجي firebase::Future طريقة لتحديد حالة اكتمال طلبات معالجة الأسلوب غير المتزامن.

تُعرِض جميع وظائف UMP C++ وطلبات استدعاء الطرق التي تعمل بشكل غير متزامن Future ، كما توفّر أيضًا دالة "النتيجة الأخيرة" لاسترداد Future من أحدث عملية.

هناك طريقتان للحصول على نتيجة من Future:

  1. استخدِم OnCompletion()، مع تضمين دالة ردّ الاتصال الخاصة بك التي يتمّ استدعاؤها عند اكتمال العملية.
  2. راجِع status() في Future بصفة دورية. عندما تتغيّر الحالة من kFutureStatusPending إلى kFutureStatusCompleted، يعني ذلك أنّه تم إكمال العملية.

بعد اكتمال العملية غير المتزامنة، عليك التحقّق من Futureerror() للحصول على رمز خطأ العملية. إذا كان رمز الخطأ هو 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، يُرجى الاطّلاع على مستندات حزمة تطوير البرامج (SDK) لـ Firebase C++ ومستندات حزمة تطوير البرامج (SDK) لإعلانات Google على الأجهزة الجوّالة C++.

عليك طلب تعديل معلومات موافقة المستخدم عند كل بدء لتطبيقك باستخدام 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.
          }
        });
      }
    });
}

راجِع القسم أعلاه للحصول على مثال على التحقّق من اكتمال العملية باستخدام ميزة فحص حلقة التحديث بدلاً من طلب استدعاء عند اكتمال العملية.

إذا كنت بحاجة إلى تنفيذ أي إجراءات بعد أن يختار المستخدم أحد الخيارات أو يغلِق النموذج، ضَع هذا المنطق في الرمز الذي يعالج Future الذي يعرضه LoadAndShowConsentFormIfRequired().

خيارات الخصوصية

يتم عرض بعض نماذج رسائل الخصوصية من نقطة دخول خيارات الخصوصية التي يعرضها الناشر، ما يتيح للمستخدمين إدارة خيارات الخصوصية في أي وقت. لمزيد من المعلومات عن الرسالة التي تظهر للمستخدمين عند نقطة دخول خيارات الخصوصية، اطّلِع على أنواع رسائل المستخدمين المتاحة.

طلب الإعلانات بعد الحصول على موافقة المستخدم

قبل طلب الإعلانات، استخدِم ConsentInfo::GetInstance()‑> CanRequestAds() للتحقّق مما إذا كان قد تم الحصول على موافقة من المستخدم:

في ما يلي الأماكن التالية التي يمكنك التحقّق منها لمعرفة ما إذا كان بإمكانك طلب عرض الإعلانات أثناء جمع الموافقة:

  • بعد أن تجمع حزمة تطوير البرامج (SDK) لـ UMP الموافقة في الجلسة الحالية.
  • بعد الاتصال بـ RequestConsentInfoUpdate() مباشرةً قد يكون قد تم الحصول على الموافقة في جلسة التطبيق السابقة من خلال "حزمة تطوير البرامج (SDK) لمنصّة User Messaging Platform".
.

إذا حدث خطأ أثناء عملية جمع الموافقة، تحقّق ممّا إذا كان بإمكانك طلب عرض الإعلانات. تستخدِم حزمة تطوير البرامج (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);
    }
    

فرض موقع جغرافي

توفّر حزمة تطوير البرامج (SDK) لمنصّة UMP طريقة لاختبار سلوك تطبيقك كما لو كان الجهاز يقع في مناطق مختلفة، مثل المنطقة الاقتصادية الأوروبية أو المملكة المتحدة، باستخدام 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 الطريقة Reset() لإجراء ذلك.

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