问题描述
我目前正在使用Google的consent-library(不推荐使用)来请求欧洲用户的个性化广告同意。该文档指定,如果用户的同意状态已设置为PERSONALIZED或NON_PERSONALIZED,则可以forward consent to the Google Mobile Ads SDK进行以下操作:
Bundle extras = new Bundle();
extras.putString("npa","1");
AdRequest request = new AdRequest.Builder()
.addNetworkExtrasBundle(AdMobAdapter.class,extras)
.build();
现在,我想迁移到新的Unified Messaging Platform SDK for Android。该文档非常简单,但是仅说明了如何获得同意,而不说明如何使用同意。这是否意味着在使用新的Android版UMP SDK时,当我们为不同意个性化广告的用户请求AdMob广告时,我们不再需要将"npa"
设置为"1"
了吗?
EDIT 2020年8月25日
昨天我发现了这个conversation,来自Mobile Ads SDK团队的人回答了我在这里提出的相同问题。他说:
我们的SDK将保留通过 npa = 1 的旧版“通过同意”,直到另行通知为止。
EDIT 2020年8月31日
我开始了一个new conversation,在这里我问的是与本文中相同的问题,但是没有得到任何答复。
解决方法
借助新的统一消息平台,Google可以作为Consent Managing Platform使用。这些CMP使用TCF字符串存储用户同意首选项。 Google检查此TCF字符串以查看可以展示哪些广告;
根据Google documentation:
当满足以下所有条件时,Google将投放个性化广告:
- 最终用户授予Google同意存储和/或访问 设备上的信息
- 创建个性化的广告资料
- 选择个性化广告
并建立了Google的合法权益(或同意,即发布者将其CMP配置为要求该出价):
- 选择基本广告
- 衡量广告效果
- 应用市场研究以生成受众见解
- 开发和改进产品
如果不满足个性化广告的同意要求,则当满足以下所有条件时,Google将投放非个性化广告:
- 在设备上存储和/或访问信息
建立了合法利益(或同意,即发布者将其CMP配置为请求CMP):
- 选择基本广告
-
衡量广告效果 -
应用市场研究以生成受众见解 -
开发和改进产品 - 在供应商列表中启用Google。
10月20日更新: 显然,不再需要3,4,5来显示用于提供此信息的非个人广告,例如@Georg。
如果以上条件均未满足,则Google不会展示广告。
我希望这能回答您的问题,但是如果您需要更多信息,请告诉我!
,只要记住这些句子:
永不放弃,杯子总是装满一半:-)->要乐观!
因此,将不再有“解决方案”来改变欧洲的有效规定。我们可以做的是这样:
当用户在资金选择表中单击“同意”或单击“提交”后,如果关闭对话框,某些参数将保存在android的默认共享首选项中!在IOS上发生了同样的事情(因此每个人都可以快速轻松地编写此解决方案
就像提供有限应用程序的“我们”权利之前一样。这意味着像在您可以提供带有限制的精简版本和要购买的完整版本之前一样。
所以我们能做的就是读取首选键。
此处描述了透明度和同意框架的首选项键: https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#in-app-details
我们需要以下偏好键才能读取(Android或IOS):
IABTCF_PurposeLegitimateInterests
IABTCF_VendorConsents
IABTCF_PurposeConsents
因此,根据这些值,我们可以检查在关闭表单后是否投放广告或“不”投放广告。
然后,您可以阻止应用中的重要选项,并可能显示一个对话框:
“广告已被禁用。您正在使用该应用的简易版。您可以改变主意或购买专业版等,等等。”
->也许在解释“启用广告”后添加按钮,然后再次显示该表格或“购买专业版”
这取决于您在这里做什么!
我的课是在kotlin或Java中!
您的工作: 将Google的UMP SDK放到您的依赖中,并在admob帐户中为您的应用设置资金选择!然后编写例程以设置资金选择表格。
在资金选择中,仅添加“ Google”作为供应商!
https://developers.google.com/admob/ump/android/quick-start
您仍然需要自己编写很多程序才能使一切正常运行,但是无论是否投放广告,此类都将至少帮助您获取信息。另外,您必须告诉自己一切如何工作以更深入地了解这一点。
记住!!!
始终使用admob中的测试ID进行测试!切勿使用生产ID,否则您可以 麻烦您的帐户!仅当您想先进行测试时,才在admob中使用测试ID创建一个新的测试应用!
如何使用课程:
Consentfunctions consentfunction;
consentfunction = new Consentfunctions(this);
// Check if Ads are serving
if (consentfunction.AdsAreServing()) {
// No need to do anything because everything is fine
} else {
// Decide what to do here. Block important functions of your app
// and open a help page with explanations etc. etc
}
Java代码:
public class ConsentFunctions {
private ConsentInformation consentInformation;
SharedPreferences.Editor editor;
private Context mContext;
private String consinfosaved;
private String vendorconsent;
private SharedPreferences preferences;
private String LegitimateInterests;
public ConsentFunctions(Context context){
mContext = context;
preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
consentInformation = UserMessagingPlatform.getConsentInformation(mContext);
}
public Boolean AdsAreServing() {
vendorconsent = preferences.getString("IABTCF_VendorConsents","");
LegitimateInterests = preferences.getString("IABTCF_PurposeLegitimateInterests","");
// Not required = not in europe -- return true because everything is fine !
if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.NOT_REQUIRED) {
return true;
}
Boolean vendoractive = vendorconsent.contains("1");
consinfosaved = preferences.getString("IABTCF_PurposeConsents","0");
switch (consinfosaved) {
case "1011": // Personal 1 - rest legitimate interest
case "1111111011": // Personal 2
case "1111001011": // Personal 3
case "1000001011": // Non personal ok
case "1100001011": // Non Peronal ok
case "11": // Non Personal ok - rest is legitimate interest
case "1111001001":
case "1": // Non personalized
{
// Check also if vendor is activated
if (!vendoractive) {
return false;
}
else {
// Legitimate must be always = 0100111011 and vendor contains 1
if (LegitimateInterests.equals("0100111011") || LegitimateInterests.equals("0100001011"))
return true;
else
return false;
}
}
default: {
return false;
}
}
}
}
科特琳代码:
class ConsentFunctionsKotlin(private val mContext: Context) {
private val consentInformation: ConsentInformation
var editor: SharedPreferences.Editor
private var consinfosaved: String? = null
private var vendorconsent: String? = null
private val preferences: SharedPreferences
private var LegitimateInterests: String? = null
init {
preferences = PreferenceManager.getDefaultSharedPreferences(mContext)
consentInformation = UserMessagingPlatform.getConsentInformation(mContext)
}
fun AdsAreServing(): Boolean {
vendorconsent = preferences.getString("IABTCF_VendorConsents","")
LegitimateInterests = preferences.getString("IABTCF_PurposeLegitimateInterests","")
// Not required = not in europe -- return true because everything is fine !
if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.NOT_REQUIRED) {
return true
}
val vendoractive = vendorconsent!!.contains("1")
consinfosaved = preferences.getString("IABTCF_PurposeConsents","0")
return when (consinfosaved) {
"1111001001","1011","1111111011","1111001011","1000001011","1100001011","11","1" -> {
// Check also if vendor is activated
if (!vendoractive) {
false
} else {
// Legitimate must be always = 0100111011 and vendor contains 1
if (LegitimateInterests == "0100111011" || LegitimateInterests == "0100001011") true else false
}
}
else -> {
false
}
}
}
}