根据 Google《欧盟地区用户意见征求政策》,您必须向位于欧洲经济区 (EEA) 和英国的用户披露某些信息,在法律有相应要求的情况下,并获得 Cookie 的使用同意,才能使用个人数据(如 AdID)来投放广告。此政策反映了欧盟《电子隐私指令》和《一般数据保护条例》(GDPR) 的要求。
为了帮助发布商履行此政策规定的职责,Google 提供了 User Messaging Platform (UMP) SDK。UMP SDK 现已更新,支持最新的 IAB 标准。所有这些配置现在都可以在 Ad Manager “隐私权和消息”中轻松处理。
前提条件
- 完成入门指南。
- 在Ad Manager 帐号的隐私权和消息标签页上配置消息。如需了解详情,请参阅隐私权和消息简介。
- 如果您正在处理与 GDPR 相关的要求,请参阅 IAB 要求对欧盟地区用户意见征求消息的影响。
用户消息类型
如需查看完整的受支持消息列表,请参阅 用户消息类型 。如需了解有关实现每种消息类型的具体说明,请参阅左侧导航栏。
使用 Gradle 安装
如果您使用的是 Google 移动广告 SDK 19.8.0 或更高版本,则可以跳过此 Gradle 安装步骤。否则,请在应用的 build.gradle
中添加 UMP SDK,如下所示:
dependencies {
// This dependency is automatically included by Google Mobile Ads SDK 19.8.0
// or higher.
implementation 'com.google.android.ump:user-messaging-platform:2.0.0'
}
更改应用的 build.gradle
后,请务必将项目与 Gradle 文件同步。
更新清单
然后从 Ad Manager 的“移动应用”部分获取应用 ID
AndroidManifest.xml
中:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.rewardedinterstitialexample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- Sample app ID: ca-app-pub-3940256099942544~3347511713 -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
确定是否需要显示消息
每次启动应用时,您都应在加载表单之前使用 requestConsentInfoUpdate()
请求更新用户的意见征求信息。这样可以确定您的用户是否需要提供用户意见征求结果(如果尚未提供或者用户意见征求结果已过期)。
consentInformation
对象中的信息。
在应用启动时检查状态的示例如下:
Java
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import com.google.android.ump.ConsentForm; 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; private ConsentForm consentForm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set tag for under age of consent. false means users are not under // age. ConsentRequestParameters params = new ConsentRequestParameters .Builder() .setTagForUnderAgeOfConsent(false) .build(); consentInformation = UserMessagingPlatform.getConsentInformation(this); consentInformation.requestConsentInfoUpdate( this, params, new ConsentInformation.OnConsentInfoUpdateSuccessListener() { @Override public void onConsentInfoUpdateSuccess() { // The consent information state was updated. // You are now ready to check if a form is available. } }, new ConsentInformation.OnConsentInfoUpdateFailureListener() { @Override public void onConsentInfoUpdateFailure(FormError formError) { // Handle the error. } }); } }
Kotlin
package com.example.myapplication import com.google.android.ump.ConsentForm 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 private lateinit var consentForm: ConsentForm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Set tag for under age of consent. false means users are not under // age. val params = ConsentRequestParameters .Builder() .setTagForUnderAgeOfConsent(false) .build() consentInformation = UserMessagingPlatform.getConsentInformation(this) consentInformation.requestConsentInfoUpdate( this, params, OnConsentInfoUpdateSuccessListener { // The consent information state was updated. // You are now ready to check if a form is available. }, OnConsentInfoUpdateFailureListener { // Handle the error. }) } }
加载表单(如果可用)
在显示表单之前,您需要先确定表单是否可用。表单不可用的原因可能是用户启用了受限的广告跟踪,或者您已将这些用户标记为“未达到同意年龄”。
如需检查表单是否可用,请使用您之前创建的the isConsentFormAvailable()
method on the ConsentInformation
instance 。
然后,添加一个加载表单所需的封装方法:
Java
... consentInformation.requestConsentInfoUpdate( this, params, new ConsentInformation.OnConsentInfoUpdateSuccessListener() { @Override public void onConsentInfoUpdateSuccess() { // The consent information state was updated. // You are now ready to check if a form is available. if (consentInformation.isConsentFormAvailable()) { loadForm(); } } }, new ConsentInformation.OnConsentInfoUpdateFailureListener() { @Override public void onConsentInfoUpdateFailure(FormError formError) { // Handle the error. } }); } public void loadForm() { } }
Kotlin
... consentInformation.requestConsentInfoUpdate( this, params, OnConsentInfoUpdateSuccessListener { // The consent information state was updated. // You are now ready to check if a form is available. if (consentInformation.isConsentFormAvailable) { loadForm() } }, OnConsentInfoUpdateFailureListener { // Handle the error. }) } fun loadForm() { } }
如需加载表单,请使用 the static loadConsentForm()
method on the UserMessagingPlatform
class,
Java
public void loadForm() { // Loads a consent form. Must be called on the main thread. UserMessagingPlatform.loadConsentForm( this, new UserMessagingPlatform.OnConsentFormLoadSuccessListener() { @Override public void onConsentFormLoadSuccess(ConsentForm consentForm) { MainActivity.this.consentForm = consentForm; } }, new UserMessagingPlatform.OnConsentFormLoadFailureListener() { @Override public void onConsentFormLoadFailure(FormError formError) { // Handle the error. } } ); }
Kotlin
fun loadForm() { // Loads a consent form. Must be called on the main thread. UserMessagingPlatform.loadConsentForm( this, UserMessagingPlatform.OnConsentFormLoadSuccessListener { this.consentForm = consentForm }, UserMessagingPlatform.OnConsentFormLoadFailureListener { // Handle the error. } ) }
根据需要显示表单
在确定表单是否可用并完成加载后,在ConsentForm
实例上通过show()
方法显示表单。
使用之前的consentInformation
对象检查consent status 并更新loadForm()
方法:
Java
public void loadForm() { // Loads a consent form. Must be called on the main thread. UserMessagingPlatform.loadConsentForm( this, new UserMessagingPlatform.OnConsentFormLoadSuccessListener() { @Override public void onConsentFormLoadSuccess(ConsentForm consentForm) { MainActivity.this.consentForm = consentForm; if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.REQUIRED) { consentForm.show( MainActivity.this, new ConsentForm.OnConsentFormDismissedListener() { @Override public void onConsentFormDismissed(@Nullable FormError formError) { if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.OBTAINED) { // App can start requesting ads. } // Handle dismissal by reloading form. loadForm(); } }); } } }, new UserMessagingPlatform.OnConsentFormLoadFailureListener() { @Override public void onConsentFormLoadFailure(FormError formError) { // Handle Error. } } ); }
Kotlin
fun loadForm() { // Loads a consent form. Must be called on the main thread. UserMessagingPlatform.loadConsentForm( this, UserMessagingPlatform.OnConsentFormLoadSuccessListener { this.consentForm = consentForm if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.REQUIRED) { consentForm.show( this, ConsentForm.OnConsentFormDismissedListener { if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.OBTAINED) { // App can start requesting ads. } // Handle dismissal by reloading form. loadForm() } ) } }, UserMessagingPlatform.OnConsentFormLoadFailureListener { // Handle the error. } ) }
如果您需要在用户做出选择或关闭表单后执行操作,请将相应逻辑放入表单的完成处理程序或回调中。
测试
强制调试地理位置
UMP SDK 提供了一种测试应用行为的方式,就像使用 the setDebugGeography
method on ConsentDebugSettings.Builder
的设备位于欧洲经济区 (EEA) 或英国内一样。
您必须在应用的调试设置中提供经过哈希处理的测试设备 ID 才能使用调试功能。如果您在未设置该值的情况下调用requestConsentInfoUpdate()
,您的应用将在运行时记录经过哈希处理的所需 ID。
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); consentInformation.requestConsentInfoUpdate(this, params, new ConsentInformation.OnConsentInfoUpdateSuccessListener() { @Override public void onConsentInfoUpdateSuccess() { // The consent information state was updated. // You are now ready to check if a form is available. } }, new ConsentInformation.OnConsentInfoUpdateFailureListener() { @Override public void onConsentInfoUpdateFailure(FormError formError) { // Handle the error. } });
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) consentInformation.requestConsentInfoUpdate( this, params, OnConsentInfoUpdateSuccessListener { // The consent information state was updated. // You are now ready to check if a form is available. }, OnConsentInfoUpdateFailureListener { // Handle the error. }) }
借助 DebugGeography
,您可以选择将地理位置强制设置为以下选项之一:
调试地理位置 | 说明 |
---|---|
DEBUG_GEOGRAPHY_DISABLED |
调试地理位置功能已停用。 |
DEBUG_GEOGRAPHY_EEA |
对于调试设备,地理位置会显示为欧洲经济区 (EEA)。 |
DEBUG_GEOGRAPHY_NOT_EEA |
对于调试设备,地理位置会显示为不在欧洲经济区 (EEA)。 |
请注意,调试设置仅适用于测试设备。无需将模拟器添加到您的设备 ID 列表中,因为模拟器已默认启用测试。
重置用户同意情况
通过 UMP SDK 测试应用时,您可能会发现重置 SDK 的状态很实用,因为您可以模拟用户的首次安装体验。该 SDK 提供的 reset()
方法可实现此目的。
Java
consentInformation.reset();
Kotlin
consentInformation.reset()
如果您决定从项目中完全移除 UMP SDK,也应调用 reset()
。