获得用户消息平台的同意

前提条件

请参阅IAB 要求对欧盟地区用户意见征求消息有何影响

简介

根据 Google 欧盟地区用户意见征求政策,您必须向位于欧洲经济区 (EEA) 内和英国境内的用户披露相关信息;在法律有相应要求的情况下,您必须征得他们的同意才能使用 Cookie 或其他本地存储方式;您同样必须征得他们的同意才能使用个人数据(如 AdID)来投放广告。此政策反映了欧盟《电子隐私指令》和《一般数据保护条例》(GDPR) 的要求。

为了帮助发布商履行此政策规定的职责,Google 提供了 User Messaging Platform (UMP) SDK,它取代了之前的开源 Consent SDK。UMP SDK 已更新,可支持最新的 IAB 标准。我们还简化了设置用户意见征求表单和列出广告合作伙伴的流程。现在,可以在AdMob 隐私权和消息中轻松处理所有这些配置。

最好在每次用户启动应用时加载表单,即使您不需要征得用户同意也不例外,这样,表单就可以随时显示,以防用户想要更改其用户意见征求设置。

本指南将逐步介绍如何安装 SDK、实现 IAB 解决方案以及启用测试功能。

使用 Gradle 进行安装

将库添加到您的应用的 build.gradle 中:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.google.android.ump:user-messaging-platform:2.0.0'
}

完成后,别忘了同步 Gradle。

将应用 ID 添加到“ AndroidManifest.xml”

按照帮助中心说明获取您的应用 ID。

将您的应用 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">
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="YOUR-APP-ID"/>
        <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>

使用 SDK

SDK 以线性方式使用。使用 SDK 的步骤如下:

  1. 请求最新的用户意见征求信息。
  2. 检查是否需要征得用户同意。
  3. 检查表单是否可用,以及加载表单。
  4. 演示表单。
  5. 为用户提供更改同意情况的方法。

我们建议您在每次应用启动时请求更新用户意见征求信息。这决定了您的用户是否需要提供同意声明。

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 underage of consent. false means users are not underage.
        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.
                }
            });
    }
}

加载表单(如有)

确定您要征求用户同意后,下一步是确定是否有表单可供使用。

有很多原因会导致表单无法使用,例如:

  • 用户已启用有限的广告跟踪功能。
  • 您已将用户标记为未达到同意年龄。

如需检查表单是否可用,请对 ConsentInformation 实例使用 isConsentFormAvailable() 方法。添加用于加载表单的封装容器方法:

...
       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() {

    }
}

如需加载表单,您将使用 UserMessagingPlatform 类上的静态 loadConsentForm() 方法。只能从主线程调用此方法。按如下方式更改 loadForm() 方法:

public void loadForm() {
    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
            }
        }
    );
}

根据需要呈现表单

如需呈现表单,请在 ConsentForm 实例上使用 show() 方法。在呈现表单之前,您应该确定用户是否需要同意。如需检查是否需要征得用户同意,请检查 ConsentInformation 对象的 getConsentStatus() 方法,该方法会返回 ConsentInformation.ConsentStatus 类型的枚举。有以下四种可能的值:

  • ConsentStatus.UNKNOWN:意见征求状态未知。
  • ConsentStatus.REQUIRED:需要用户同意,但尚未获得用户同意。
  • ConsentStatus.NOT_REQUIRED:不需要征得用户同意。例如,用户不在欧洲经济区 (EEA) 或英国。
  • ConsentStatus.OBTAINED:已获得用户同意。个性化设置未定义。

按如下方式更改 loadForm() 方法:

public void loadForm(){
    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) {
                                    // Handle dismissal by reloading form.
                                    loadForm();
                                }
                            });

                }

            }
        },
        new UserMessagingPlatform.OnConsentFormLoadFailureListener() {
            @Override
            public void onConsentFormLoadFailure(FormError formError) {
                /// Handle Error.
            }
        }
   );
}

如果不需要征求用户意见,您也可以保留对表单的引用,以便用户能够更改其意见状态。

测试

强制使用地理位置

UMP SDK 提供了一种方法来测试应用行为,就像使用 ConsentDebugSettings.Builder 上的 setDebugGeography() 方法将设备定位在 EEA 内一样。

若要使用调试功能,您需要在应用的调试设置中提供测试设备的经过哈希处理的 ID。如果在未设置此值的情况下调用 requestConsentInfoUpdate(),您的应用将在运行时记录所需的 ID 哈希。

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

如需强制 SDK 将设备视为不在欧洲经济区 (EEA) 或英国境内,请使用 DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA。请注意,调试设置仅适用于测试设备。模拟器无需添加到设备 ID 列表中,因为它们默认启用了测试。

使用 UMP SDK 测试应用时,重置 SDK 的状态可能会很有用,让您能够模拟用户的首次安装体验。 SDK 提供了 reset 方法来执行此操作。

consentInformation.reset();

延迟应用衡量(可选)

默认情况下,Google 移动广告 SDK 会初始化应用衡量标准,然后在应用启动时立即开始向 Google 发送用户级事件数据。 此初始化行为确保您可以启用 AdMob 用户指标,而无需对代码做出其他更改。

但是,如果您的应用需要在征求用户意见后才能发送这些事件,则可以延迟应用衡量,直到您显式初始化移动广告 SDK 或加载广告为止。

要延迟应用衡量,请在 AndroidManifest.xml 中添加以下 <meta-data> 标记。

<manifest>
     <application>
        <!-- Delay app measurement until MobileAds.initialize() is called. -->
        <meta-data
            android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT"
            android:value="true"/>
    </application>
</manifest>

中介

如果您使用中介功能,则需要根据您选择在应用中使用的用户意见征求框架,为中介合作伙伴处理意见征求方式。Google 支持 IAB 用户意见征求框架,但也允许您拥有自己的自定义用户意见征求解决方案。下面详细介绍了如何处理每个选项下的中介。 详细了解我们的用户意见征求解决方案

UMP SDK 和移动广告 SDK 都不会将用户意见征求信息转发给中介合作伙伴。相反,在使用 IAB 解决方案时,UMP SDK 会将用户意见征求状态信息写入本地存储空间,并且每个中介合作伙伴的 SDK 都有责任读取相应的键。请务必与每个第三方广告联盟联系,以确定其是否支持 IAB 解决方案。

如果您使用自定义用户意见征求解决方案,则有责任将第三方的 SDK 状态通知给第三方 SDK。如需详细了解如何向相关第三方传递意见征求信息,请参阅每个中介合作伙伴的集成指南,了解实现详情。

此部分中的代码可用于任何版本的 Google 移动广告 SDK。无论您是否使用 Consent SDK 征求用户意见,均可使用这些代码。

默认的 Google 移动广告 SDK 行为是投放个性化广告。如果用户仅同意接收非个性化广告,您可以配置 AdRequest 对象,以指定只应请求非个性化广告。无论用户是否在欧洲经济区 (EEA) 内,以下代码都会导致请求非个性化广告:

Bundle extras = new Bundle();
extras.putString("npa", "1");

AdRequest request = new AdRequest.Builder()
    .addNetworkExtrasBundle(AdMobAdapter.class, extras)
    .build();

如果请求的是非个性化广告,则广告请求网址目前会包含 &npa=1。但请注意,这是 Google 移动广告 SDK 的内部实现细节,随时可能会出现更改。