我自己一直在解决这个问题,虽然我没有你所有问题的答案,但我已经找到了一些。
UMP 将其输出写入此处SharedPreferences
概述的某些字符串。您可以编写一些辅助方法来查询这些字符串,以查明用户给予的广告许可级别或用户是否是 EEA。
如何检查用户是否是 EEA?您可以检查IABTCF_gdprApplies
SharedPreferences 中的整数,如果它是 1,则用户是 EEA。如果为 0,则用户不是。
如何获得同意类型?这部分变得更加复杂。此处的 Google 文档概述了个性化和非个性化广告所需的权限。为此,您需要查看 SharedPreference 中的 4 个字符串:IABTCF_PurposeConsents
、、IABTCF_PurposeLegitimateInterests
和IABTCF_VendorConsents
IABTCF_VendorLegitimateInterests
. 正如其他人所指出的,用户几乎不可能实际选择非个性化广告配置,因为他们不仅必须选择“在设备上存储信息”,而且还必须滚动浏览数百个非字母组织的供应商来查找并选择“Google”(这些字符串中的供应商 ID 为 755)。这意味着出于所有实际目的,他们要么选择个性化广告(全部同意),要么拥有一个不错的无广告应用程序,他们无需支付任何费用。您至少可以使用这些检查来设置付费墙、禁用云功能或以其他方式处理您认为合适的情况。
我做了一些辅助方法来找到这些状态。
科特林
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)
//https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#in-app-details
//https://support.google.com/admob/answer/9760862?hl=en&ref_topic=9756841
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)
// Minimum required for at least non-personalized ads
return hasConsentFor(listOf(1), purposeConsent, hasGoogleVendorConsent)
&& hasConsentOrLegitimateInterestFor(listOf(2,7,9,10), purposeConsent, purposeLI, hasGoogleVendorConsent, hasGoogleVendorLI)
}
fun canShowPersonalizedAds(): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext)
//https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#in-app-details
//https://support.google.com/admob/answer/9760862?hl=en&ref_topic=9756841
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)
}
// Check if a binary string has a "1" at position "index" (1-based)
private fun hasAttribute(input: String, index: Int): Boolean {
return input.length >= index && input[index-1] == '1'
}
// Check if consent is given for a list of purposes
private fun hasConsentFor(purposes: List<Int>, purposeConsent: String, hasVendorConsent: Boolean): Boolean {
return purposes.all { p -> hasAttribute(purposeConsent, p)} && hasVendorConsent
}
// Check if a vendor either has consent or legitimate interest for a list of purposes
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)
}
}
迅速
func isGDPR() -> Bool {
let settings = UserDefaults.standard
let gdpr = settings.integer(forKey: "IABTCF_gdprApplies")
return gdpr == 1
}
// Check if a binary string has a "1" at position "index" (1-based)
private func hasAttribute(input: String, index: Int) -> Bool {
return input.count >= index && String(Array(input)[index-1]) == "1"
}
// Check if consent is given for a list of purposes
private func hasConsentFor(_ purposes: [Int], _ purposeConsent: String, _ hasVendorConsent: Bool) -> Bool {
return purposes.allSatisfy { i in hasAttribute(input: purposeConsent, index: i) } && hasVendorConsent
}
// Check if a vendor either has consent or legitimate interest for a list of purposes
private func hasConsentOrLegitimateInterestFor(_ purposes: [Int], _ purposeConsent: String, _ purposeLI: String, _ hasVendorConsent: Bool, _ hasVendorLI: Bool) -> Bool {
return purposes.allSatisfy { i in
(hasAttribute(input: purposeLI, index: i) && hasVendorLI) ||
(hasAttribute(input: purposeConsent, index: i) && hasVendorConsent)
}
}
private func canShowAds() -> Bool {
let settings = UserDefaults.standard
//https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#in-app-details
//https://support.google.com/admob/answer/9760862?hl=en&ref_topic=9756841
let purposeConsent = settings.string(forKey: "IABTCF_PurposeConsents") ?? ""
let vendorConsent = settings.string(forKey: "IABTCF_VendorConsents") ?? ""
let vendorLI = settings.string(forKey: "IABTCF_VendorLegitimateInterests") ?? ""
let purposeLI = settings.string(forKey: "IABTCF_PurposeLegitimateInterests") ?? ""
let googleId = 755
let hasGoogleVendorConsent = hasAttribute(input: vendorConsent, index: googleId)
let hasGoogleVendorLI = hasAttribute(input: vendorLI, index: googleId)
// Minimum required for at least non-personalized ads
return hasConsentFor([1], purposeConsent, hasGoogleVendorConsent)
&& hasConsentOrLegitimateInterestFor([2,7,9,10], purposeConsent, purposeLI, hasGoogleVendorConsent, hasGoogleVendorLI)
}
private func canShowPersonalizedAds() -> Bool {
let settings = UserDefaults.standard
//https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#in-app-details
//https://support.google.com/admob/answer/9760862?hl=en&ref_topic=9756841
// required for personalized ads
let purposeConsent = settings.string(forKey: "IABTCF_PurposeConsents") ?? ""
let vendorConsent = settings.string(forKey: "IABTCF_VendorConsents") ?? ""
let vendorLI = settings.string(forKey: "IABTCF_VendorLegitimateInterests") ?? ""
let purposeLI = settings.string(forKey: "IABTCF_PurposeLegitimateInterests") ?? ""
let googleId = 755
let hasGoogleVendorConsent = hasAttribute(input: vendorConsent, index: googleId)
let hasGoogleVendorLI = hasAttribute(input: vendorLI, index: googleId)
return hasConsentFor([1,3,4], purposeConsent, hasGoogleVendorConsent)
&& hasConsentOrLegitimateInterestFor([2,7,9,10], purposeConsent, purposeLI, hasGoogleVendorConsent, hasGoogleVendorLI)
}