12

我对 UMP SDK 的实现有很多困惑。除了google,我没有找到太多信息或完整的教程。我正在关注这个这个但无法理解以下问题:

  1. MobileAds.initialize()获得请求同意后是否需要打电话?如果是这样,那么应该在哪里调用它?征得同意后可能会调用:

    public void onConsentFormLoadSuccess(ConsentForm consentForm) {
        if(consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.OBTAINED) {
    }
    }
    
  2. 我如何检查用户是否来自 EEA?我想根据用户位置请求同意或初始化移动广告。在Consent SDK中,有一个方法isRequestLocationInEeaOrUnknown(),但这个 SDK 已被弃用。我在 UMP SDK 中没有找到类似的东西。一种方法可能是 alwaysrequestConsentInfoUpdate并调用isConsentFormAvailableinside onConsentInfoUpdateSuccess。如果用户不是来自 EEA,则此方法返回 false。

  3. 我总是得到同意类型consentInformation.getConsentType()0 或 UnKnown。我尝试过不同的组合,但总是 0。

  4. 是否需要将同意信息转发给 AdMob SDK 或 SDK 将处理它。

  5. 关于调解,我需要同意信息,但不知道如何获得。来自文档:The UMP SDK writes consent status information to local storage

  6. 在 AdMob -> 欧盟用户同意中,我的中介合作伙伴之一未包含在Commonly used set of ad technology providers. 如果我使用Custom set of ad technology providers,我是否需要包括所有Commonly used set of ad technology providers有 198 家广告技术提供商的地方。或者在 Funding Choices 中包含广告技术提供商就足够了。

4

4 回答 4

6

据我体验/了解,通过用户消息传递平台进行的 Google 资助选择(实际上甚至不清楚为什么它有两个不同的名称)在欧盟内完全没用。

欢迎您纠正我,但正如我在 2021 年 8 月 3 日所经历的那样:

如果用户单击“管理选项”,然后单击“提交”并将“在设备上存储和/或访问信息”开关关闭,则 AdMob 不会向用户显示任何广告。因此,您最终可能会为资源(云服务、员工等)付费以向您的用户提供免费应用程序。 根据问题出现的开始日期(我在本主题中看到的帖子和评论的日期),对于 Google 和/或 AdMob,它是一个低优先级问题。permitInformation.getConsentType() 总是返回值 0。这实际上证明(或至少我认为)这个问题在他们的列表中的优先级有多低。至少可以通过这个 getter 检查用户是否同意提供非个性化广告。然后我们可以向他展示如何正确选择退出并让他免费使用该应用程序。但是,这似乎是出于开发人员的利益。

再次,欢迎任何人纠正我,也许只有我有这种负面经历。

于 2021-03-08T10:36:35.667 回答
2

我自己一直在解决这个问题,虽然我没有你所有问题的答案,但我已经找到了一些。

UMP 将其输出写入此处SharedPreferences概述的某些字符串。您可以编写一些辅助方法来查询这些字符串,以查明用户给予的广告许可级别或用户是否是 EEA。

  1. 如何检查用户是否是 EEA?您可以检查IABTCF_gdprAppliesSharedPreferences 中的整数,如果它是 1,则用户是 EEA。如果为 0,则用户不是。

  2. 如何获得同意类型?这部分变得更加复杂。此处的 Google 文档概述了个性化和非个性化广告所需的权限。为此,您需要查看 SharedPreference 中的 4 个字符串:IABTCF_PurposeConsents、、IABTCF_PurposeLegitimateInterestsIABTCF_VendorConsentsIABTCF_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)
}
于 2021-07-09T02:33:56.000 回答
0

我有同样的疑问,特别是在第 3 点,即使在我的情况下,同意类型始终为 0。我在此视频中看到,基于该值初始化了不同的 adRequest

关于第 2 点,我将 Consentdebugsettings 设置为用户无 EEA(DEBUG_GEOGRAPHY_NOT_EEA,与官方指南中所做的略有不同),并且方法 consentInformation.isConsentFormAvailable() 返回 false

于 2020-12-26T22:26:30.847 回答
0

我想提出一些想法:

1. 获得请求同意后是否需要调用MobileAds.initialize()?

是的

2. 我如何检查用户是否来自 EEA?

您可以像这样使用许可信息.getConsentStatus():

if (consentInformation.getConsentStatus()== ConsentInformation.ConsentStatus.NOT_REQUIRED) {

}

您可以使用以下命令测试此功能:

ConsentRequestParameters.Builder consentRequest = new ConsentRequestParameters.Builder()
    .setTagForUnderAgeOfConsent(false);
        
ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(activity)
    .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA)
    //.setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
    //.setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_DISABLED)
    .addTestDeviceHashedId("Your device Hashed Id")
    .build();
    
consentRequest.setConsentDebugSettings(debugSettings);
ConsentRequestParameters consentRequestParameters = consentRequest.build()

但是不要忘记每次都调用许可信息.reset()。

3. 我总是得到同意类型的许可信息。getConsentType() 0。

getConsentType() 没用,已在 user-messaging-platform:2.0.0 中删除。对我来说原因很简单:有了这个新平台,不再有双重状态,用户授权,用户未授权。现在它更像是 3 个状态:1-yes_for_all、2-no_for_all、3-customized_by_user

4. 是否需要将同意信息转发给 AdMob SDK 或 SDK 会处理。

Admob SDK 将处理它。这就是为什么您不需要 getConsentType() 除非您想显示用户选择。但为此,最好重新打开同意书。太糟糕了,同意书没有加载用户的正确设置。

5. 关于调解,我需要同意信息,但不知道如何获得。

正如@Tyler V 所述

6. 在 AdMob -> EU 用户同意中,我的一个中介合作伙伴不包括在常用的广告技术提供商集中。如果我使用自定义广告技术提供商集,我是否需要包括所有常用的广告技术提供商集,其中有 198 个广告技术提供商。或者在 Funding Choices 中包含广告技术提供商就足够了。

我认为在 Funding Choices 中包含广告技术提供商就足够了。

于 2022-01-03T04:16:39.743 回答