開始使用

根據 Google 歐盟地區使用者同意聲明 政策,您必須 向歐洲經濟區境內的使用者揭露特定資訊 取得使用 Cookie 或其他本機儲存空間的同意聲明。 並根據法律要求使用個人資料 (如 AdID) 放送廣告。 本政策是配合《歐盟地區電子通訊隱私指令》和 《一般資料保護規則》(GDPR) 規定)。

為了協助發布商根據這項政策履行自身職責,Google 提供 User Messaging Platform (UMP) SDK。UMP SDK 已更新,現已支援 符合最新的 IAB 標準這些設定現在都很方便 處理 AdMob 隱私權與傳送訊息

必要條件

  • Android API 級別 21 以上

建立訊息類型

使用以下其中一則文字建立使用者訊息: 可用的使用者訊息類型 中,隱私權與訊息分頁 AdMob 。 讓他們使用服務帳戶UMP SDK 會嘗試顯示 透過應用程式 ID AdMob 建立的使用者訊息 您在專案中設定的內容如果未設定應用程式訊息,則 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 檔案的專案。

新增應用程式 ID

您可以在「 AdMob UI: 將身分證件新增至 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 載入表單並立即顯示 可用資料 activitycallback 關閉表單後,系統就會呼叫 已完成。如果不需要同意聲明, 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. 實作 UI 元素,例如應用程式設定頁面中的按鈕。 觸發隱私權選項表單
  2. 完成後 loadAndShowConsentFormIfRequired() 請查看 privacyOptionsRequirementStatus() 會決定是否要顯示 可顯示隱私權選項表單的 UI 元素。
  3. 當使用者與 UI 元素互動時, showPrivacyOptionsForm() 顯示表單,方便使用者 隨時更新自己的隱私權選項。

以下範例說明如何在 Google 記錄檔中顯示隱私權選項表單 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)
}

測試

如要在開發過程中測試應用程式內整合功能,請按照下列步驟操作: 這些步驟以程式輔助方式註冊測試裝置。請務必移除 程式碼,在發布應用程式前設定測試裝置 ID。

  1. 呼叫 requestConsentInfoUpdate()
  2. 查看記錄輸出中是否有類似以下範例的訊息, 顯示您的裝置 ID 以及如何將其新增為測試裝置:

    Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231") to set this as a debug device.
    
  3. 將測試裝置 ID 複製到剪貼簿。

  4. 修改程式碼以 ConsentDebugSettings.Builder().addTestDeviceHashedId() 並傳入 測試裝置 ID 清單。

強迫一個地理

UMP SDK 可讓您測試應用程式行為,就像測試裝置 地址在歐洲經濟區或英國境內,並使用 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