UMP将其输出写入SharedPreferences中的一些属性,详见
此处。您可以编写一些辅助方法来查询这些属性,以了解用户授予的广告同意级别或用户是否属于欧洲经济区(EEA),但您需要查看的不仅仅是VendorConsents字符串。
通常有5个属性您需要查找,以确定是否会提供广告服务:
IABTCF_gdprApplies
- 一个整数(0或1),表示用户是否在欧洲经济区
IABTCF_PurposeConsents
- 一个由0和1组成的字符串,最多包含10个条目,表示用户是否同意了10个不同的目的
IABTCF_PurposeLegitimateInterests
- 一个由0和1组成的字符串,最多包含10个条目,表示应用程序是否对10个不同的目的具有合法利益
IABTCF_VendorConsents
- 一个由0和1组成的任意长度的字符串,表示给定供应商是否已获得了上述目的的同意。每个供应商都有一个ID,表示它在字符串中的位置。例如,Google的ID是755,所以如果Google已获得同意,则该字符串中的第755个字符将是“1”。完整的供应商列表可在这里找到。
IABTCF_VendorLegitimateInterests
- 类似于供应商同意字符串,但它表示供应商是否对先前指定的目的具有合法利益。
根据Google的文档
这里,关于UMP资金选择表单与广告服务相关的实际结果实际上只有几种:
1. 用户点击了“同意全部” - 上述字符串将全部为1,并且将显示个性化广告。
2. 用户点击了“不同意任何内容” - 将不显示任何广告。
3. 用户点击了“管理”并选择了存储同意(目的1),并在非按字母顺序列出的供应商巨大列表中滚动选择了“Google” - 将显示非个性化广告。
4. 用户点击了“管理”并执行了比前一步骤更少的操作(例如,选择了存储和基本广告,但没有手动从供应商列表中选择Google) - 再次,将不显示任何广告。
这是一个相当不理想的选项集,因为#3几乎不可能发生,而#2和#4会导致用户在不支付费用的情况下获得无广告的应用程序。从实际角度来看,这已经移除了传统同意SDK中的“非个性化广告”选项(以及购买无广告应用程序的选项),并用完全禁用广告来替代。
我写了一些辅助方法,至少让您查询用户实际选择的内容并相应地采取行动。
fun isGDPR(): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
val gdpr = prefs.getInt("IABTCF_gdprApplies", 0)
return gdpr == 1
}
fun canShowAds(): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
val purposeConsent = prefs.getString("IABTCF_PurposeConsents", "") ?: ""
val vendorConsent = prefs.getString("IABTCF_VendorConsents","") ?: ""
val vendorLI = prefs.getString("IABTCF_VendorLegitimateInterests","") ?: ""
val purposeLI = prefs.getString("IABTCF_PurposeLegitimateInterests","") ?: ""
val googleId = 755
val hasGoogleVendorConsent = hasAttribute(vendorConsent, index=googleId)
val hasGoogleVendorLI = hasAttribute(vendorLI, index=googleId)
return hasConsentFor(listOf(1), purposeConsent, hasGoogleVendorConsent)
&& hasConsentOrLegitimateInterestFor(listOf(2,7,9,10), purposeConsent, purposeLI, hasGoogleVendorConsent, hasGoogleVendorLI)
}
fun canShowPersonalizedAds(): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
val purposeConsent = prefs.getString("IABTCF_PurposeConsents", "") ?: ""
val vendorConsent = prefs.getString("IABTCF_VendorConsents","") ?: ""
val vendorLI = prefs.getString("IABTCF_VendorLegitimateInterests","") ?: ""
val purposeLI = prefs.getString("IABTCF_PurposeLegitimateInterests","") ?: ""
val googleId = 755
val hasGoogleVendorConsent = hasAttribute(vendorConsent, index=googleId)
val hasGoogleVendorLI = hasAttribute(vendorLI, index=googleId)
return hasConsentFor(listOf(1,3,4), purposeConsent, hasGoogleVendorConsent)
&& hasConsentOrLegitimateInterestFor(listOf(2,7,9,10), purposeConsent, purposeLI, hasGoogleVendorConsent, hasGoogleVendorLI)
}
private fun hasAttribute(input: String, index: Int): Boolean {
return input.length >= index && input[index-1] == '1'
}
private fun hasConsentFor(purposes: List<Int>, purposeConsent: String, hasVendorConsent: Boolean): Boolean {
return purposes.all { p -> hasAttribute(purposeConsent, p)} && hasVendorConsent
}
private fun hasConsentOrLegitimateInterestFor(purposes: List<Int>, purposeConsent: String, purposeLI: String, hasVendorConsent: Boolean, hasVendorLI: Boolean): Boolean {
return purposes.all { p ->
(hasAttribute(purposeLI, p) && hasVendorLI) ||
(hasAttribute(purposeConsent, p) && hasVendorConsent)
}
}
注意:PreferenceManager.getDefaultSharedPreferences并没有被弃用,你只需要确保导入了androidx的包(import androidx.preference.PreferenceManager)。如果你导入了错误的包(import android.preference.PreferenceManager),它会被标记为已弃用。