שנתחיל?

בכפוף להסכמת משתמשים של Google באיחוד האירופי מדיניות, עליך להציג הודעות גילוי נאות מסוימות למשתמשים באזור הכלכלי האירופי (EEA) בנוסף עם בריטניה ולקבל את הסכמתם לשימוש בקובצי Cookie או באמצעים אחרים לאחסון מקומי, במקומות שבהם הדבר נדרש על פי חוק, וכן להשתמש במידע אישי (כגון מזהה פרסום) לצורך הצגת מודעות. המדיניות הזו משקפת את הדרישות שמפורטות ב-ePrivacy Directive (ההנחיה בנושא פרטיות ותקשורת אלקטרונית) של האיחוד האירופי General Data Protection Regulation (התקנות הכלליות להגנה על מידע, GDPR).

כדי לעזור לבעלי תוכן דיגיטלי למלא את החובות שלהם במסגרת המדיניות הזו, Google מציעה User Messaging Platform (UMP) SDK. UMP SDK עודכן כדי לתמוך בהתאם לתקנים העדכניים ביותר של IAB. כל ההגדרות האישיות האלה יכולות עכשיו מטופל Ad Manager בפרטיות העברת הודעות.

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

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

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

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

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

התקנה באמצעות Gradle

מוסיפים את התלות של Google User Messaging Platform SDK למודול ברמת האפליקציה, קובץ Gradle, בדרך כלל app/build.gradle:

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

אחרי שמבצעים את השינויים ב-build.gradle של האפליקציה, חשוב לסנכרן את באמצעות קובצי Gradle.

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

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

<manifest>
  <application>
    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID"
        android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
  </application>
</manifest>

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

טעינה והצגה של טופס הסכמה, לפי הצורך

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

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

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

    new Thread(
            () -> {
              // Initialize the Google Mobile Ads SDK on a background thread.
              
              MobileAds.initialize(this, initializationStatus -> {});
              runOnUiThread(
                  () -> {
                    // TODO: Request an ad.
                    // loadInterstitialAd();
                  });
              
            })
        .start();
  }
}

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
    }

    val backgroundScope = CoroutineScope(Dispatchers.IO)
    backgroundScope.launch {
      
      MobileAds.initialize(this@MainActivity) {}
      runOnUiThread {
        // TODO: Request an ad.
        // loadInterstitialAd()
      }
      
    }
  }
}

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

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

לשם כך:

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

אילוץ מיקום גיאוגרפי

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

Java

consentInformation.reset();

Kotlin

consentInformation.reset()

דוגמאות ב-GitHub

דוגמאות לשילוב של UMP SDK: Java | Kotlin