征求欧洲用户同意

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

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

为了帮助发布商履行此政策规定的职责,Google 提供了 Consent SDK。Consent SDK 是一个开源库,提供用于征求用户意见的实用函数。完整的源代码可在GitHub 上找到。

Google 投放的广告可分为个性化广告和非个性化广告,投放这两类广告都需要在欧洲经济区 (EEA) 内征求用户同意。默认情况下,向 Google 发出的广告请求会投放个性化广告,并根据用户先前收集的数据选择广告。Google 还支持配置广告请求,以便投放非个性化广告。 详细了解个性化广告和非个性化广告

本指南介绍了如何使用 Consent SDK 征求用户意见,以及在征得用户同意后如何将用户意见转发给 Google 移动广告 SDK

前提条件

应用可以使用指向 Google Maven 代码库的 Gradle 依赖项导入 Consent SDK。如需使用该代码库,您需要在应用的项目级 build.gradle 文件中引用该代码库。请打开该文件,然后查找 allprojects 部分:

项目级 build.gradle 示例(节选)

allprojects {
    repositories {
        google()
        jcenter()
    }
}

如果上面的 google() 指令不存在,请添加该指令。

接下来,打开应用的应用级 build.gradle 文件,并找到“ dependencies”部分。

应用级 build.gradle 示例(节选)

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.ads.consent:consent-library:1.0.6'
}

请添加上面的粗体代码行,该代码会指示 Gradle 提取最新版本的 Consent SDK。完成后,保存文件并执行 Gradle 同步。

在使用 Consent SDK 中的任何其他方法之前,您应更新意见征求状态,以确保 Consent SDK 拥有与您在AdMob 界面中选择的广告技术提供商有关的最新信息。如果广告技术提供商列表在用户上次同意后发生了变化,用户意见征求状态会重新设为未知状态。

如果您不使用中介

如果您未使用中介,可通过以下两种方法实现 Consent SDK 来征求用户意见。

一种方法是使用 Consent SDK 向用户显示由 Google 呈现的用户意见征求表单。用户意见征求表单会显示您在 AdMob界面中选择的广告技术提供商列表。Consent SDK 会存储用户的意见回复。

另一种方法是使用 Consent SDK 从 AdMob中动态检索完整的广告技术提供商列表,详情请参阅由发布商管理的用户意见征求。不过,在这种情况下,您需要确定如何向用户呈现提供商列表,并向用户显示您自己的同意书。

一旦用户做出了意见选择,您就可以要求 Consent SDK 存储用户的意见选择(如存储由发布商管理的用户意见征求中所述)。

征得用户同意后,如果用户仅同意接收非个性化广告,则您需要将用户意见转发给 Google 移动广告 SDK

如果您使用 AdMob 中介

您可以使用 Consent SDK 从 AdMob中动态检索完整的广告技术提供商列表,详情请参阅由发布商管理的用户意见征求。您需要确定需要向其他广告联盟提供哪些其他广告技术提供商以供用户同意。

作为应用开发者,您需要为 Consent SDK 返回的广告技术提供商以及其他广告联盟的用户意见征求征求用户意见。如果用户仅同意接收非个性化广告,那么您还需要手动存储用户的意见回复,并将用户意见转发给 Google 移动广告 SDK

Google 目前无法为中介广告联盟征求和处理用户意见,因此您需要为每个广告联盟单独征求和处理用户意见。如需了解实现详情,请参阅每个中介合作伙伴的集成指南

更新用户意见状态

使用 Consent SDK 时,建议您在每次应用启动时确定用户的同意情况。为此,请在 ConsentInformation 实例上调用 requestConsentInfoUpdate()

import com.google.ads.consent.*;

public class MainActivity extends Activity {
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        ConsentInformation consentInformation = ConsentInformation.getInstance(context);
        String[] publisherIds = {"pub-0123456789012345"};
        consentInformation.requestConsentInfoUpdate(publisherIds, new ConsentInfoUpdateListener() {
            @Override
            public void onConsentInfoUpdated(ConsentStatus consentStatus) {
                 // User's consent status successfully updated.
            }

            @Override
            public void onFailedToUpdateConsentInfo(String errorDescription) {
                 // User's consent status failed to update.
            }
        });
        ...
    }
    ...
}

调用 requestConsentInfoUpdate() 需要两个参数:

  • 一组有效且完全激活的发布商 ID,供您的应用发出广告请求。 查找您的发布商 ID

  • ConsentInfoUpdateListener 的一个实例。

如果成功更新用户意见信息,系统会通过 ConsentInfoUpdateListeneronConsentInfoUpdated() 方法提供更新后的用户意见状态。返回的 ConsentStatus 可能具有下列值:

用户意见状态 定义
ConsentStatus.PERSONALIZED 用户已同意投放个性化广告。
ConsentStatus.NON_PERSONALIZED 用户已同意接收非个性化广告。
ConsentStatus.UNKNOWN 用户既未同意接收也未拒绝接收个性化广告或非个性化广告。

用户意见信息更新成功后,您还可以检查 ConsentInformation.getInstance(context).isRequestLocationInEeaOrUnknown(),以查看用户是否位于欧洲经济区内或者请求位置是否未知。

如果 isRequestLocationInEeaOrUnknown() 方法返回 false,则表明用户不在欧洲经济区内,并且无需根据《欧盟地区用户意见征求政策》征求用户意见。您可以向 Google 移动广告 SDK 发出广告请求。

如果 isRequestLocationInEeaOrUnknown() 方法返回 true

Google 的Consent SDK。提供了两种征求用户意见的方法:

请务必为用户提供更改或撤消同意的选项。

由 Google 呈现的用户意见征求表单是在应用内容之上显示的全屏可配置表单。您可以将表单配置为向用户显示以下选项组合:

  • 同意观看个性化广告
  • 同意观看非个性化广告
  • 使用付费版应用,而不是观看广告

您应仔细查看同意文本:如果您通过 Google 使用应用创收,那么系统默认显示的消息可能是正确的;但我们无法就适合您的同意文本提供法律建议。如需更新由 Google 呈现的用户意见征求表单中的用户意见文本,可根据需要修改 Consent SDK 中的 consentform.html 文件。

使用 ConsentForm 类配置并显示由 Google 呈现的用户意见征求表单。以下代码演示了如何使用所有三个用户意见选项构建 ConsentForm

URL privacyUrl = null;
try {
    // TODO: Replace with your app's privacy policy URL.
    privacyUrl = new URL("https://www.your.com/privacyurl");
} catch (MalformedURLException e) {
    e.printStackTrace();
    // Handle error.
}
ConsentForm form = new ConsentForm.Builder(context, privacyUrl)
    .withListener(new ConsentFormListener() {
        @Override
        public void onConsentFormLoaded() {
            // Consent form loaded successfully.
        }

        @Override
        public void onConsentFormOpened() {
            // Consent form was displayed.
        }

        @Override
        public void onConsentFormClosed(
                ConsentStatus consentStatus, Boolean userPrefersAdFree) {
            // Consent form was closed.
        }

        @Override
        public void onConsentFormError(String errorDescription) {
            // Consent form error.
        }
    })
    .withPersonalizedAdsOption()
    .withNonPersonalizedAdsOption()
    .withAdFreeOption()
    .build();

上述方法使用以下选项准备由 Google 呈现的用户意见征求表单:

withListener()
ConsentForm 注册监听器。ConsentFormListener 中每种可替换的方法均对应用户意见征求表单生命周期中的一个事件。
可替换的方法
onConsentFormLoaded 用户意见征求表单已成功加载。
onConsentFormError 用户意见征求表单加载失败。errorDescription 参数提供了对错误的说明。
onConsentFormOpened 用户意见征求表单已打开。
onConsentFormClosed 用户意见征求表单已关闭。该方法的参数提供了以下信息:
  • consentStatus 是一个 ConsentStatus 值,用于描述更新后的用户意见状态。
  • 当用户选择使用付费版本应用而不观看广告时,userPrefersAdFree 的值为 true
withPersonalizedAdsOption()
表示用户意见征求表单应显示个性化广告选项。
withNonPersonalizedAdsOption()
表示用户意见征求表单应显示非个性化广告选项。
withAdFreeOption()
表示用户意见征求表单应显示无广告应用选项。

创建 ConsentForm 对象后,请调用 ConsentFormload() 方法加载用户意见征求表单,如下所示:

form.load();

如需向用户显示由 Google 呈现的用户意见征求表单,请在 ConsentForm 实例上调用 show(),如下所示:

form.show();

在用户选择一个选项并关闭表单后,Consent SDK 会保存用户的选择并触发 onConsentFormClosed 事件。您可以监听此事件并将用户意见转发给 Google 移动广告 SDK

由发布商管理的用户意见征求

如果您选择自行征求用户意见,则可以使用 ConsentInformation 类的 getAdProviders() 方法获取与您应用中使用的发布商 ID 相关联的广告技术提供商。请注意,凡是针对您的发布商 ID 配置的所有广告技术提供商,您均需为其征求用户意见。

您必须先等待 ConsentInfoUpdateListeneronConsentInfoUpdate() 方法(如更新用户意见状态部分所述),然后才能调用 getAdProviders()

List<AdProvider> adProviders =
    ConsentInformation.getInstance(context).getAdProviders();

然后,您就可以使用广告技术提供商列表自行征求用户意见。

征得用户同意后,请使用 ConsentInformation 类的 setConsentStatus() 方法记录与用户响应相对应的 ConsentStatus

ConsentInformation.getInstance(context)
    .setConsentStatus(ConsentStatus.PERSONALIZED);

向 Consent SDK 报告用户同意后,您可以将用户意见转发给 Google 移动广告 SDK

要允许用户更新意见征求状态,只需在用户选择更新其同意情况时重复征求用户意见部分中列出的步骤即可。

如果发布商知道用户未达到同意年龄,则所有广告请求都必须设置 TFUA(用于表示用户位于欧洲且未达到法定承诺年龄的标记)。若要在您的应用发出的所有广告请求中包含此标记,请调用 setTagForUnderAgeOfConsent(true)。此设置将在以后的所有广告请求中生效。

ConsentInformation.getInstance(context).setTagForUnderAgeOfConsent(true);

启用 TFUA 设置后,Google 呈现的用户意见征求表单将无法加载。所有包含 TFUA 的广告请求都将不符合投放个性化广告和再营销功能的条件。TFUA 会禁止向第三方广告服务提供商(例如广告衡量像素和第三方广告服务器)发送请求。

如需从广告请求中移除 TFUA,请调用 setTagForUnderAgeOfConsent(false)

测试

Consent SDK 的行为会有所不同,具体取决于ConsentInformation.getInstance(context).isRequestLocationInEeaOrUnknown() 的值。 例如,如果用户不在欧洲经济区 (EEA) 内,则无法加载用户意见征求表单。

为便于在欧洲经济区内外测试您的应用,Consent SDK 支持在调用 Consent SDK 中的任何其他方法之前设置的调试选项。

  1. 按照更新用户意见状态部分中的说明调用 requestConsentInfoUpdate。然后运行您的应用。检查 logcat 输出以获取以下日志:

    I/ConsentInformation: Use
    ConsentInformation.getInstance(context).addTestDevice("33BE2250B43518CCDA7DE426D04EE231")
    to get test ads on this device.
  2. 使用 logcat 中的广告 ID 将您的设备指定为测试设备:

    ConsentInformation.getInstance(context).addTestDevice("33BE2250B43518CCDA7DE426D04EE231");
  3. 最后,调用 setDebugGeography 来设置用于测试的首选地理位置。

    // Geography appears as in EEA for test devices.
    ConsentInformation.getInstance(context).
        setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_EEA);
    // Geography appears as not in EEA for debug devices.
    ConsentInformation.getInstance(context).
        setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA);

完成这些步骤后,更新用户意见征求状态的调用会将您的调试地理位置考虑在内。

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

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

Java

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

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

Kotlin

val extras = Bundle()
extras.putString("npa", "1")

val request = AdRequest.Builder()
    .addNetworkExtrasBundle(AdMobAdapter::class.java, extras)
    .build()

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

延迟应用衡量(可选)

默认情况下,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>

常见问题解答

Consent SDK 支持多少家广告技术提供商?
Consent SDK 未对发布商选择启用的广告技术提供商数量设定限制。
如果我在 AdMob 界面中更改我的选择,SDK 返回的广告技术提供商列表是否会自动更新?
会,如果您对AdMob 界面中的广告技术提供商列表做出更改,这些更改会在大约 1 小时后传播到 Google 的广告服务器。