根据 Google《欧盟地区用户意见征求政策》,您必须向位于欧洲经济区 (EEA) 以及英国境内的用户披露相关信息;在法律有要求的情况下,必须征得他们的同意才能使用 Cookie 或其他本地存储方式;此外,您必须同意他们使用个人数据(例如 AdID)来投放广告。此政策反映了欧盟《电子隐私指令》和《一般数据保护条例》(GDPR) 的要求。
为了帮助发布商履行此政策规定的职责,Google 提供了 User Messaging Platform (UMP) SDK。UMP SDK 已更新,可支持最新的 IAB 标准。所有这些配置现在都可以在“隐私权和消息”中轻松处理。 Ad Manager
前提条件
- 完成入门指南
- 如果您正在处理与 GDPR 相关的要求,请参阅IAB 要求对欧盟地区用户意见征求消息的影响
创建消息类型
创建用户消息时,您可以使用 可用的用户消息类型 (在 Ad Manager 账号的隐私权和消息标签页下)创建用户消息。UMP SDK 会尝试显示通过 Ad Manager 中设置的应用 ID 创建的用户消息。如果没有为您的应用配置消息,SDK 会返回错误。
如需了解详情,请参阅 隐私权和消息简介。
征求用户同意
每次启动应用时,您都应使用 requestConsentInfoUpdate()
请求更新用户的意见征求信息。这决定了您的用户是否需要提供用户意见征求结果(如果尚未提供或者用户意见征求结果已过期)。
在应用启动时检查状态的示例如下:
@override
void initState() {
super.initState();
// Create a ConsentRequestParameters object.
final params = ConsentRequestParameters();
// Request an update for the consent information.
ConsentInformation.instance.requestConsentInfoUpdate(
params,
() async {
// TODO: Load and present the consent form.
},
(FormError error) {
// Handle the error.
},
);
}
根据需要加载并显示用户意见征求表单
收到最新的用户意见征求状态后,请对ConsentForm
类调用loadAndShowConsentFormIfRequired()
以加载用户意见征求表单。如果需要征求用户意见,则 SDK 会加载一个表单,并立即 从提供的 中显示该表单。 callback
在表单关闭后 调用。如果不需要征得用户同意,系统会立即 callback
操作。
@override
void initState() {
super.initState();
// Create a ConsentRequestParameters object.
final params = ConsentRequestParameters();
// Request an update for the consent information.
ConsentInformation.instance.requestConsentInfoUpdate(
params,
() async {
ConsentForm.loadAndShowConsentFormIfRequired((loadAndShowError) {
if (loadAndShowError != null) {
// Consent gathering failed.
}
// Consent has been gathered.
});
},
(FormError error) {
// Handle the error.
},
);
}
如果您需要在用户做出选择或关闭表单后执行操作,请将相应逻辑放入表单的 callback中。
提出广告请求
在应用中请求广告之前,请检查您是否已使用 canRequestAds()
征得用户的同意。征求用户意见时需要检查以下两个方面:
- 在当前会话中征求用户意见后。
- 调用
requestConsentInfoUpdate()
后立即执行。 可能已经在之前的会话中征得用户同意。作为延迟时间最佳做法,我们建议您不要等待回调完成,这样您就可以在应用启动后尽快开始加载广告。
如果在征求用户意见的过程中发生错误,您仍然应该尝试请求广告。UMP SDK 会使用上一个会话的用户意见征求状态。
class AppExampleState extends State<AppExample> {
// Use a bool to initialize the Mobile Ads SDK and load ads once.
var _isMobileAdsInitializeCalled = false;
@override
void initState() {
super.initState();
// Create a ConsentRequestParameters object.
final params = ConsentRequestParameters();
// Request an update for the consent information.
ConsentInformation.instance.requestConsentInfoUpdate(
params,
() async {
ConsentForm.loadAndShowConsentFormIfRequired((loadAndShowError) {
if (loadAndShowError != null) {
// Consent gathering failed.
}
// Consent has been gathered.
_initializeMobileAdsSDK();
});
},
(FormError error) {
// Handle the error.
},
);
// Check if you can initialize the Mobile Ads SDK in parallel while
// checking for new consent information. Consent obtained in the
// previous session can be used to request ads.
_initializeMobileAdsSDK();
}
void _initializeMobileAdsSDK() async {
if (_isMobileAdsInitializeCalled) {
return;
}
// Initialize the Mobile Ads SDK if the SDK has gathered consent aligned with
// the app's configured messages.
var canRequestAds = await ConsentInformation.instance.canRequestAds();
if (canRequestAds) {
setState(() {
_isMobileAdsInitializeCalled = true;
});
// Initialize the Mobile Ads SDK.
MobileAds.instance.initialize();
// TODO: Request an ad.
}
}
}
隐私设置选项
一些用户意见征求表单要求用户随时修改同意声明。如需实现隐私权选项按钮(如果需要),请按照以下步骤操作。
要实现这一目标,需要完成以下步骤:
- 实现可以触发隐私权选项表单的界面元素,例如应用设置页面中的按钮。
-
loadAndShowConsentFormIfRequired()
完成后,请检查getPrivacyOptionsRequirementStatus()
,以确定是否显示可以呈现隐私选项表单的界面元素。 - 当用户与您的界面元素互动时,调用
showPrivacyOptionsForm()
以显示该表单,以便用户随时更新其隐私选项。
class AppExampleState extends State<AppExample> {
static const _privacySettingsText = 'Privacy Settings';
// Use a bool to initialize the Mobile Ads SDK and load ads once.
var _isMobileAdsInitializeCalled = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App Example',
home: Scaffold(
appBar: AppBar(
title: const Text('App Example'),
actions: _isMobileAdsSDKInitialized
// Regenerate the options menu to include a privacy setting.
? _privacySettingsAppBarAction()
: null
),
body: // ...
),
);
}
List<Widget> _privacySettingsAppBarAction() {
return <Widget>[
FutureBuilder(
future: ConsentInformation.instance.isPrivacyOptionsRequired(),
builder: (context, snapshot) {
final bool visibility = snapshot.data ?? false;
return Visibility(
visible: visibility,
child: PopupMenuButton<String>(
onSelected: (String result) {
if (result == _privacySettingsText) {
ConsentForm.showPrivacyOptionsForm((formError) {
if (formError != null) {
debugPrint(
"${formError.errorCode}: ${formError.message}");
}
});
}
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: _privacySettingsText,
child: Text(_privacySettingsText))
],
));
})
];
}
}
测试
如果您希望在开发过程中测试应用中的集成,请按照以下步骤以编程方式注册测试设备。在发布应用之前,请务必移除用于设置这些测试设备 ID 的代码。
- 调用
requestConsentInfoUpdate()
。 检查日志输出是否存在类似于以下示例的消息,该示例显示了您的设备 ID 以及如何将其添加为测试设备:
Android
Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231") to set this as a debug device.
iOS
<UMP SDK>To enable debug mode for this device, set: UMPDebugSettings.testDeviceIdentifiers = @[2077ef9a63d2b398840261c8221a0c9b]
将测试设备 ID 复制到剪贴板。
修改代码, 调用
ConsentDebugSettings.testIdentifiers
,并传入 测试设备 ID 列表。ConsentDebugSettings debugSettings = ConsentDebugSettings( testIdentifiers: ["TEST-DEVICE-HASHED-ID"], ); ConsentRequestParameters params = ConsentRequestParameters(consentDebugSettings: debugSettings); ConsentInformation.instance.requestConsentInfoUpdate(params, () async { // ... };
强制设置地理位置
UMP SDK 可让您使用 the DebugGeography
field on ConsentDebugSettings
来测试应用的行为,就像设备位于欧洲经济区 (EEA) 或英国一样。请注意,调试设置仅适用于测试设备。
ConsentDebugSettings debugSettings = ConsentDebugSettings(
debugGeography: DebugGeography.debugGeographyEea,
testIdentifiers: ["TEST-DEVICE-HASHED-ID"],
);
ConsentRequestParameters params =
ConsentRequestParameters(consentDebugSettings: debugSettings);
ConsentInformation.instance.requestConsentInfoUpdate(params, () async {
// ...
};
重置同意情况
通过 UMP SDK 测试应用时,您可能会发现重置 SDK 的状态非常有用,因为您可以模拟用户的首次安装体验。该 SDK 提供的 reset()
方法可实现此目的。
ConsentInformation.instance.reset();