البدء

بموجب سياسة موافقة المستخدم في الاتحاد الأوروبي التي تتّبعها Google، يجب الإفصاح عن معلومات معيّنة للمستخدمين في المنطقة الاقتصادية الأوروبية (EEA) وفي المملكة المتحدة والحصول على موافقتهم على استخدام ملفات تعريف الارتباط أو غير ذلك من البيانات المحفوظة على أجهزتهم المحلية، حيثما يكون ذلك مطلوبًا بموجب القانون، وعلى استخدام البيانات الشخصية (مثل AdID) لعرض الإعلانات. تعكس هذه السياسة شروط "التوجيه الأوروبي بشأن الخصوصية الإلكترونية" و"اللائحة العامة لحماية البيانات" (GDPR).

لمساعدة الناشرين في الوفاء بالتزاماتهم بموجب هذه السياسة، تقدِّم Google حزمة تطوير البرامج (SDK) لمنصّة User Messaging Platform (UMP). تم تحديث حزمة تطوير البرامج (SDK) الخاصة بمنصة UMP لتتوافق مع أحدث معايير IAB. يمكن الآن التعامل مع كل هذه الإعدادات بسهولة في AdMob الخصوصية والمراسلة.

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

  • المستوى 21 من واجهة برمجة تطبيقات Android أو مستوى أعلى

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

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

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

التثبيت باستخدام Gradle

أضِف الملحقية لحزمة تطوير البرامج (SDK) لمنصة Google User Messaging Platform إلى ملف Gradle على مستوى التطبيق في الوحدة، ويكون عادةً app/build.gradle:

dependencies {
  implementation("com.google.android.ump:user-messaging-platform:2.2.0")
}

بعد إجراء التغييرات على build.gradle في تطبيقك، تأكَّد من مزامنة مشروعك مع ملفات Gradle.

عليك طلب تعديل معلومات موافقة المستخدم عند كل عملية إطلاق للتطبيق باستخدام requestConsentInfoUpdate(). يحدِّد هذا الإجراء ما إذا كان المستخدم بحاجة إلى تقديم موافقته إذا لم يسبق له تقديم موافقته أو إذا انتهت صلاحيتها.

في ما يلي مثال على كيفية التحقّق من الحالة من MainActivity في طريقة onCreate().

Java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.google.android.ump.ConsentInformation;
import com.google.android.ump.ConsentRequestParameters;
import com.google.android.ump.FormError;
import com.google.android.ump.UserMessagingPlatform;

public class MainActivity extends AppCompatActivity {
  private ConsentInformation consentInformation;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Create a ConsentRequestParameters object.
    ConsentRequestParameters params = new ConsentRequestParameters
        .Builder()
        .build();

    consentInformation = UserMessagingPlatform.getConsentInformation(this);
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        (OnConsentInfoUpdateSuccessListener) () -> {
          // TODO: Load and show the consent form.
        },
        (OnConsentInfoUpdateFailureListener) requestConsentError -> {
          // Consent gathering failed.
          Log.w(TAG, String.format("%s: %s",
              requestConsentError.getErrorCode(),
              requestConsentError.getMessage()));
        });
  }
}

Kotlin

package com.example.myapplication

import com.google.android.ump.ConsentInformation
import com.google.android.ump.ConsentInformation.OnConsentInfoUpdateFailureListener
import com.google.android.ump.ConsentInformation.OnConsentInfoUpdateSuccessListener
import com.google.android.ump.ConsentRequestParameters
import com.google.android.ump.UserMessagingPlatform

class MainActivity : AppCompatActivity() {
  private lateinit var consentInformation: ConsentInformation

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Create a ConsentRequestParameters object.
    val params = ConsentRequestParameters
        .Builder()
        .build()

    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        ConsentInformation.OnConsentInfoUpdateSuccessListener {
          // TODO: Load and show the consent form.
        },
        ConsentInformation.OnConsentInfoUpdateFailureListener {
          requestConsentError ->
          // Consent gathering failed.
          Log.w(TAG, "${requestConsentError.errorCode}: ${requestConsentError.message}")
        })
  }
}

تحميل نموذج موافقة وعرضه إذا لزم الأمر

ملاحظة مُهمّة: واجهات برمجة التطبيقات التالية متوافقة مع الإصدار 2.1.0 أو الإصدارات الأحدث من حزمة تطوير البرامج (SDK) الخاصة بمنصة UMP.

بعد حصولك على أحدث حالة للموافقة، تواصَل مع loadAndShowConsentFormIfRequired() الصف ConsentForm لتحميل نموذج موافقة. إذا كانت حالة الموافقة مطلوبة، تُحمِّل حزمة تطوير البرامج (SDK) نموذجًا وتعرضه على الفور من activityالتي تم توفيرها. يتم استدعاء callback بعد إغلاق النموذج. في حال لم تكن الموافقة مطلوبة، يتم طلب callback على الفور.

Java

public class MainActivity extends AppCompatActivity {
  private ConsentInformation consentInformation;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Create a ConsentRequestParameters object.
    ConsentRequestParameters params = new ConsentRequestParameters
        .Builder()
        .build();

    consentInformation = UserMessagingPlatform.getConsentInformation(this);
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        (OnConsentInfoUpdateSuccessListener) () -> {
          UserMessagingPlatform.loadAndShowConsentFormIfRequired(
            this,
            (OnConsentFormDismissedListener) loadAndShowError -> {
              if (loadAndShowError != null) {
                // Consent gathering failed.
                Log.w(TAG, String.format("%s: %s",
                    loadAndShowError.getErrorCode(),
                    loadAndShowError.getMessage()));
              }

              // Consent has been gathered.
            }
          );
        },
        (OnConsentInfoUpdateFailureListener) requestConsentError -> {
          // Consent gathering failed.
          Log.w(TAG, String.format("%s: %s",
              requestConsentError.getErrorCode(),
              requestConsentError.getMessage()));
        });
  }
}

Kotlin

class MainActivity : AppCompatActivity() {
  private lateinit var consentInformation: ConsentInformation

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Create a ConsentRequestParameters object.
    val params = ConsentRequestParameters
        .Builder()
        .build()

    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        ConsentInformation.OnConsentInfoUpdateSuccessListener {
          UserMessagingPlatform.loadAndShowConsentFormIfRequired(
            this@MainActivity,
            ConsentForm.OnConsentFormDismissedListener {
              loadAndShowError ->
              if (loadAndShowError != null) {
                // Consent gathering failed.
                Log.w(TAG, "${loadAndShowError.errorCode}: ${loadAndShowError.message}")
              }

              // Consent has been gathered.
            }
          )
        },
        ConsentInformation.OnConsentInfoUpdateFailureListener {
          requestConsentError ->
          // Consent gathering failed.
          Log.w(TAG, "${requestConsentError.errorCode}: ${requestConsentError.message}")
        })
  }
}

إذا كنت بحاجة إلى تنفيذ أي إجراءات بعد أن يختار المستخدم النموذج أو يرفضه، حدِّد المنطق في callback النموذج.

طلب إدراج الإعلانات

قبل طلب الإعلانات في تطبيقك، تحقّق مما إذا حصلت على موافقة من المستخدِم الذي يستخدم canRequestAds(). هناك مكانان يمكن التحقق منهما أثناء جمع الموافقات:

  1. بعد الحصول على الموافقة في الجلسة الحالية
  2. مباشرة بعد الاتصال بـ requestConsentInfoUpdate(). من المحتمَل أنّه تم الحصول على موافقة في الجلسة السابقة. من بين أفضل الممارسات التي يجب اتّباعها لوقت الاستجابة، عدم انتظار اكتمال معاودة الاتصال حتى تتمكن من البدء في تحميل الإعلانات في أقرب وقت ممكن بعد إطلاق التطبيق.

وفي حال حدوث خطأ أثناء عملية الحصول على الموافقات، عليك مع ذلك محاولة طلب الإعلانات. تستخدم حزمة تطوير البرامج (SDK) لمنصة UMP حالة الموافقة من الجلسة السابقة.

Java

public class MainActivity extends AppCompatActivity {
  private ConsentInformation consentInformation;
  // Use an atomic boolean to initialize the Google Mobile Ads SDK and load ads once.
  private final AtomicBoolean isMobileAdsInitializeCalled = new AtomicBoolean(false);
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Create a ConsentRequestParameters object.
    ConsentRequestParameters params = new ConsentRequestParameters
        .Builder()
        .build();

    consentInformation = UserMessagingPlatform.getConsentInformation(this);
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        (OnConsentInfoUpdateSuccessListener) () -> {
          UserMessagingPlatform.loadAndShowConsentFormIfRequired(
            this,
            (OnConsentFormDismissedListener) loadAndShowError -> {
              if (loadAndShowError != null) {
                // Consent gathering failed.
                Log.w(TAG, String.format("%s: %s",
                    loadAndShowError.getErrorCode(),
                    loadAndShowError.getMessage()));
              }

              // Consent has been gathered.
              if (consentInformation.canRequestAds()) {
                initializeMobileAdsSdk();
              }
            }
          );
        },
        (OnConsentInfoUpdateFailureListener) requestConsentError -> {
          // Consent gathering failed.
          Log.w(TAG, String.format("%s: %s",
              requestConsentError.getErrorCode(),
              requestConsentError.getMessage()));
        });
    
    // Check if you can initialize the Google Mobile Ads SDK in parallel
    // while checking for new consent information. Consent obtained in
    // the previous session can be used to request ads.
    if (consentInformation.canRequestAds()) {
      initializeMobileAdsSdk();
    }
  }
  
  private void initializeMobileAdsSdk() {
    if (isMobileAdsInitializeCalled.getAndSet(true)) {
      return;
    }

    // Initialize the Google Mobile Ads SDK.
    MobileAds.initialize(this);

    // TODO: Request an ad.
    // InterstitialAd.load(...);
  }
}

Kotlin

class MainActivity : AppCompatActivity() {
  private lateinit var consentInformation: ConsentInformation
  // Use an atomic boolean to initialize the Google Mobile Ads SDK and load ads once.
  private var isMobileAdsInitializeCalled = AtomicBoolean(false)
  
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Create a ConsentRequestParameters object.
    val params = ConsentRequestParameters
        .Builder()
        .build()

    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        ConsentInformation.OnConsentInfoUpdateSuccessListener {
          UserMessagingPlatform.loadAndShowConsentFormIfRequired(
            this@MainActivity,
            ConsentForm.OnConsentFormDismissedListener {
              loadAndShowError ->
              if (loadAndShowError != null) {
                // Consent gathering failed.
                Log.w(TAG, "${loadAndShowError.errorCode}: ${loadAndShowError.message}")
              }

              // Consent has been gathered.
              if (consentInformation.canRequestAds()) {
                initializeMobileAdsSdk()
              }
            }
          )
        },
        ConsentInformation.OnConsentInfoUpdateFailureListener {
          requestConsentError ->
          // Consent gathering failed.
          Log.w(TAG, "${requestConsentError.errorCode}: ${requestConsentError.message}")
        })
    
    // Check if you can initialize the Google Mobile Ads SDK in parallel
    // while checking for new consent information. Consent obtained in
    // the previous session can be used to request ads.
    if (consentInformation.canRequestAds()) {
      initializeMobileAdsSdk()
    }
  }
  
  private fun initializeMobileAdsSdk() {
    if (isMobileAdsInitializeCalled.getAndSet(true)) {
      return
    }

    // Initialize the Google Mobile Ads SDK.
    MobileAds.initialize(this)

    // TODO: Request an ad.
    // InterstitialAd.load(...)
  }
}

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

تتطلّب بعض نماذج الموافقة من المستخدم تعديل موافقته في أي وقت. التزم بالخطوات التالية لعرض زر خيارات الخصوصية إذا لزم الأمر.

ولإجراء ذلك:

  1. نفِّذ عنصر واجهة مستخدم، مثل زر في صفحة إعدادات تطبيقك، يمكن أن يؤدي إلى ظهور نموذج خيارات الخصوصية.
  2. بعد loadAndShowConsentFormIfRequired() الاكتمال، ضَع علامة في المربّع privacyOptionsRequirementStatus() لتحديد ما إذا كان سيتم عرض عنصر واجهة المستخدم الذي يمكنه عرض نموذج خيارات الخصوصية.
  3. عندما يتفاعل مستخدم مع عنصر في واجهة المستخدم، يمكنك استدعاء showPrivacyOptionsForm() لعرض النموذج حتى يتمكّن المستخدم من تعديل خيارات الخصوصية في أي وقت.

يوضّح المثال التالي كيفية تقديم نموذج خيارات الخصوصية من MenuItem.

Java

private final ConsentInformation consentInformation;

// Show a privacy options button if required.
public boolean isPrivacyOptionsRequired() {
  return consentInformation.getPrivacyOptionsRequirementStatus()
      == PrivacyOptionsRequirementStatus.REQUIRED;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
  // ...

  consentInformation = UserMessagingPlatform.getConsentInformation(this);
  consentInformation.requestConsentInfoUpdate(
      this,
      params,
      (OnConsentInfoUpdateSuccessListener) () -> {
        UserMessagingPlatform.loadAndShowConsentFormIfRequired(
          this,
          (OnConsentFormDismissedListener) loadAndShowError -> {
            // ...

            // Consent has been gathered.

            if (isPrivacyOptionsRequired()) {
              // Regenerate the options menu to include a privacy setting.
              invalidateOptionsMenu();
            }
          }
        )
      }
      // ...
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.action_menu, menu);
  MenuItem moreMenu = menu.findItem(R.id.action_more);
  moreMenu.setVisible(isPrivacyOptionsRequired());
  return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
  // ...

  popup.setOnMenuItemClickListener(
      popupMenuItem -> {
        if (popupMenuItem.getItemId() == R.id.privacy_settings) {
          // Present the privacy options form when a user interacts with
          // the privacy settings button.
          UserMessagingPlatform.showPrivacyOptionsForm(
              this,
              formError -> {
                if (formError != null) {
                  // Handle the error.
                }
              }
          );
          return true;
        }
        return false;
      });
  return super.onOptionsItemSelected(item);
}

Kotlin

private val consentInformation: ConsentInformation =
  UserMessagingPlatform.getConsentInformation(context)

// Show a privacy options button if required.
val isPrivacyOptionsRequired: Boolean
  get() =
    consentInformation.privacyOptionsRequirementStatus ==
      ConsentInformation.PrivacyOptionsRequirementStatus.REQUIRED

override fun onCreate(savedInstanceState: Bundle?) {
  ...
  consentInformation = UserMessagingPlatform.getConsentInformation(this)
  consentInformation.requestConsentInfoUpdate(
      this,
      params,
      ConsentInformation.OnConsentInfoUpdateSuccessListener {
        UserMessagingPlatform.loadAndShowConsentFormIfRequired(
          this@MainActivity,
          ConsentForm.OnConsentFormDismissedListener {
            // ...

            // Consent has been gathered.

            if (isPrivacyOptionsRequired) {
              // Regenerate the options menu to include a privacy setting.
              invalidateOptionsMenu();
            }
          }
        )
      }
      // ...
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
  menuInflater.inflate(R.menu.action_menu, menu)
  menu?.findItem(R.id.action_more)?.apply {
    isVisible = isPrivacyOptionsRequired
  }
  return super.onCreateOptionsMenu(menu)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
  // ...

  popup.setOnMenuItemClickListener { popupMenuItem ->
    when (popupMenuItem.itemId) {
      R.id.privacy_settings -> {
        // Present the privacy options form when a user interacts with
        // the privacy settings button.
        UserMessagingPlatform.showPrivacyOptionsForm(this) { formError ->
          formError?.let {
            // Handle the error.
          }
        }
        true
      }
      else -> false
    }
  }
  return super.onOptionsItemSelected(item)
}

الاختبار

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

  1. الاتصال requestConsentInfoUpdate()
  2. تحقق من مخرجات السجلّ الخاصة برسالة مشابهة للمثال التالي والتي تُظهر رقم تعريف جهازك وكيفية إضافته كجهاز اختبار:

    Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231") to set this as a debug device.
    
  3. انسخ رقم تعريف جهاز الاختبار إلى الحافظة.

  4. يُرجى تعديل الرمز الخاص بك الاتصال ConsentDebugSettings.Builder().addTestDeviceHashedId() وإرسال قائمة بأرقام تعريف الأجهزة الاختبارية.

    Java

    ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
        .addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
        .build();
    
    ConsentRequestParameters params = new ConsentRequestParameters
        .Builder()
        .setConsentDebugSettings(debugSettings)
        .build();
    
    consentInformation = UserMessagingPlatform.getConsentInformation(this);
    // Include the ConsentRequestParameters in your consent request.
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        ...
    );
    

    Kotlin

    val debugSettings = ConsentDebugSettings.Builder(this)
        .addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
        .build()
    
    val params = ConsentRequestParameters
        .Builder()
        .setConsentDebugSettings(debugSettings)
        .build()
    
    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    // Include the ConsentRequestParameters in your consent request.
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        ...
    )
    

فرض منطقة جغرافية

توفّر حزمة تطوير البرامج (SDK) لمنصة UMP طريقة لاختبار سلوك تطبيقك كما لو كان الجهاز مقيمًا في المنطقة الاقتصادية الأوروبية أو المملكة المتحدة باستخدام the setDebugGeography() method which takes a DebugGeography on ConsentDebugSettings.Builder. تجدر الإشارة إلى أنّ إعدادات تصحيح الأخطاء لا تعمل إلا على الأجهزة الاختبارية.

Java

ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
    .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
    .addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
    .build();

ConsentRequestParameters params = new ConsentRequestParameters
    .Builder()
    .setConsentDebugSettings(debugSettings)
    .build();

consentInformation = UserMessagingPlatform.getConsentInformation(this);
// Include the ConsentRequestParameters in your consent request.
consentInformation.requestConsentInfoUpdate(
    this,
    params,
    ...
);

Kotlin

val debugSettings = ConsentDebugSettings.Builder(this)
    .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
    .addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
    .build()

val params = ConsentRequestParameters
    .Builder()
    .setConsentDebugSettings(debugSettings)
    .build()

consentInformation = UserMessagingPlatform.getConsentInformation(this)
// Include the ConsentRequestParameters in your consent request.
consentInformation.requestConsentInfoUpdate(
    this,
    params,
    ...
)

عند اختبار تطبيقك باستخدام حزمة تطوير البرامج لمنصة UMP، قد يكون من المفيد إعادة ضبط حالة حزمة تطوير البرامج (SDK) كي تتمكّن من محاكاة تجربة التثبيت الأولى للمستخدم. توفر حزمة SDK الطريقة reset() لإجراء ذلك.

Java

consentInformation.reset();

Kotlin

consentInformation.reset()

أمثلة على GitHub

أمثلة على دمج حزمة تطوير البرامج (SDK) لمنصة UMP: Java | Kotlin