Как правильно внедрить UMP SDK для согласия ес?
У меня много путаницы относительно реализации UMP SDK. Я не нашел много информации или полного руководства, кроме Google. Я слежу за этим и этим, но не могу понять следующие вопросы:
Обязательно звонить
MobileAds.initialize()
после получения запрашивающего согласия? Если да, то где его называть? Он может быть вызван после получения согласия:public void onConsentFormLoadSuccess(ConsentForm consentForm) { if(consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.OBTAINED) { } }
Как мне проверить, не является ли пользователь из ЕЭЗ? Я хотел запросить согласие или инициализировать мобильные объявления в зависимости от местоположения пользователя. В Consent SDK есть метод
isRequestLocationInEeaOrUnknown()
, но этот SDK устарел. Ничего подобного в UMP SDK не нашел. Один из подходов может заключаться в том, чтобы всегдаrequestConsentInfoUpdate
и позвониisConsentFormAvailable
внутриonConsentInfoUpdateSuccess
. Этот метод возвращает false, если пользователь не из ЕЭЗ.Я всегда получаю тип согласия
consentInformation.getConsentType()
0 или неизвестно. Я пробовал использовать разные комбинации, но всегда 0.Требуется ли передавать информацию о согласии в AdMob SDK или SDK обработает это?
Что касается посредничества, мне нужна информация о согласии, но я не знаю, как ее получить. Из документов:
The UMP SDK writes consent status information to local storage
В AdMob -> Согласие пользователя из ЕС один из моих партнеров-посредников не включен в. Если я использую
Custom set of ad technology providers
, мне нужно включить всеCommonly used set of ad technology providers
где работают 198 поставщиков рекламных технологий. Или достаточно включить поставщиков рекламных технологий в список вариантов финансирования.
5 ответов
Я сам работал над этим, и, хотя у меня нет ответов на все ваши вопросы, я выяснил некоторые из них.
UMP записывает свой вывод в некоторые строки в
Как проверить, является ли пользователь ЕЭЗ? Вы можете проверить
целое число в SharedPreferences, и если оно равно 1, пользователь является EEA. Если он равен 0, пользователь не является. Как получить тип согласия? Эта часть усложняется. Документы Google здесь обрисовать , какие разрешения необходимы для персонализированных и не персонализированных объявлений. Чтобы получить это, вам нужно просмотреть 4 строки из SharedPreference:
, , а также . Как отмечали другие, для пользователя практически невозможно выбрать неперсонализированную конфигурацию рекламы, поскольку он должен не только выбрать «Хранить информацию на устройстве», но и прокрутить сотни неупорядоченных по алфавиту поставщиков, чтобы найти, а также выбрать "Google" (идентификатор поставщика 755 в этих строках). Это означает, что для всех практических целей они либо выберут персонализированную рекламу (Consent All), либо получат красивое приложение без рекламы, за которое ничего не заплатили. Вы можете, по крайней мере, использовать эти проверки, чтобы установить платный доступ, отключить облачные функции или иным образом обработать этот сценарий по своему усмотрению.
Я создал несколько вспомогательных методов для поиска этих состояний в iOS (ниже приведен код Swift - извинения, я знаю, что это вопрос Android, но его легко перевести).
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)
}
Насколько я знаю / понимаю варианты финансирования Google через платформу обмена сообщениями пользователей (на самом деле даже не ясно, почему у нее два разных названия), ПОЛНОСТЬЮ БЕСПЛАТНО ВНУТРИ ЕС.
Вы можете меня поправить, но, как я понял на 8.3.2021:
Если пользователь нажимает «Управление параметрами», а затем «Отправить» и оставляет переключатель «Хранение и / или доступ к информации на устройстве» в ВЫКЛЮЧЕННОМ состоянии, то AdMob не показывает пользователю никакой рекламы. Таким образом, вы можете в конечном итоге заплатить за ресурсы (облачные сервисы, сотрудников и т. Д.), Чтобы предоставить вашему пользователю бесплатное приложение.Исходя из начальной даты появления проблемы (даты сообщений и комментариев, которые я вижу в этой теме), это проблема низкого приоритета для Google и / или для AdMob. согласиеInformation.getConsentType() всегда возвращает значение 0. Это фактически доказывает (или, по крайней мере, я думаю), насколько низкий приоритет у этой проблемы в их списке. Можно было бы проверить, согласился ли пользователь на показ неперсонализированной рекламы, по крайней мере, через этот получатель. Затем мы могли бы показать ему инструкции, как правильно отказаться, и позволить ему использовать приложение бесплатно. Однако, похоже, это не в интересах разработчиков.
Еще раз: любой может меня поправить, может быть, только у меня был этот негативный опыт.
Я хотел бы привести некоторые мысли:
1. Нужно ли вызывать MobileAds.initialize() после получения запрашиваемого согласия?
Да, это так
2. Как мне проверить, что пользователь не из ЕЭЗ?
Вы можете использовать ConsentInformation.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()
Но не забывайте каждый раз вызыватьсогласиеInformation.reset().
3. Я всегда получаю тип согласия согласияInformation.getConsentType() 0.
getConsentType() бесполезен и был удален в пользовательской платформе обмена сообщениями:2.0.0. Для меня причина проста: с этой новой платформой больше нет двойного состояния: пользователь предоставил, пользователь не предоставил. Теперь это больше похоже на 3 состояния: 1-да_для_всех, 2-нет_для_всех, 3-настраивается_пользователем.
4. Требуется ли пересылать информацию о согласии в AdMob SDK или SDK сам ее обработает.
Admob SDK справится с этим. Вот почему вам не нужен getConsentType(), если вы не хотите показывать выбор пользователя. Но для этого лучше заново открыть форму согласия. Жаль, что форма согласия не загружает правильные настройки пользователя.
5. Что касается посредничества, мне нужна информация о согласии, но я не знаю, как ее получить.
Здесь , как заявил @Tyler V.
6. В AdMob -> Согласие пользователя из ЕС один из моих партнеров-посредников не включен в список часто используемых поставщиков рекламных технологий. Если я использую пользовательский набор поставщиков рекламных технологий, нужно ли мне включать весь часто используемый набор поставщиков рекламных технологий, где имеется 198 поставщиков рекламных технологий. Или достаточно включить поставщиков рекламных технологий в Детектор блокировки.
Я думаю, достаточно включить поставщиков рекламных технологий в Детектор блокировки.
У меня те же сомнения, особенно по пункту 3, даже в моем случае тип согласия всегда равен 0. В этом видео я видел, что на основе этого значения инициализируется другое значение adRequest.
Что касается пункта 2, я установил Consentdebugsettings с пользователем без EEA (DEBUG_GEOGRAPHY_NOT_EEA, немного отличается от того, что было сделано в официальном руководстве), и методconsentdebugsettings () вернул false
В случае использования Flutter и интереса к текущему статусу согласия это представляется возможным с помощью:
iabtcf_consent_info
https://pub.dev/packages/iabtcf_consent_info
Использование пакета выше с этим вспомогательным классом отлично работает для меня.
ВызовcanShowAds()
чтобы выяснить, должен ли пользователь использовать платный доступ.
/// Call canShowAds() to determine whether ads are to be shown at all.
/// Useful for setting up a paywall.
///
/// Methods return NULL if no consent info could be read (yet).
class AdmobConsentHelper {
/// General Data Protection Regulation (EU) (GDPR) is a regulation
/// in EU law on data protection and privacy in the European Union (EU)
/// and the European Economic Area (EEA).
Future<bool?> isGDPR() async {
return (await _consentInfo())?.gdprApplies;
}
Future<bool?> canShowAds() async {
// 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
BasicConsentInfo? info = await _consentInfo();
if (info != null) {
if (info is ConsentInfo) {
List<DataUsagePurpose> list1 = [
DataUsagePurpose.storeAndAccessInformationOnADevice // 1
];
List<DataUsagePurpose> list2 = [
DataUsagePurpose.selectBasicAds, // 2
DataUsagePurpose.measureAdPerformance, // 7
DataUsagePurpose.applyMarketResearchToGenerateAudienceInsights, // 9
DataUsagePurpose.developAndImproveProducts // 10
];
return _hasConsent(info, list1) &&
_hasConsentOrLegitimateInterest(info, list2);
}
return true;
}
return null;
}
Future<bool?> canShowPersonalizedAds() async {
// 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
BasicConsentInfo? info = await _consentInfo();
if (info != null) {
if (info is ConsentInfo) {
List<DataUsagePurpose> list1 = [
DataUsagePurpose.storeAndAccessInformationOnADevice, // 1
DataUsagePurpose.createAPersonalisedAdsProfile, // 3
DataUsagePurpose.selectPersonalisedAds, // 4
];
List<DataUsagePurpose> list2 = [
DataUsagePurpose.selectBasicAds, // 2
DataUsagePurpose.measureAdPerformance, // 7
DataUsagePurpose.applyMarketResearchToGenerateAudienceInsights, // 9
DataUsagePurpose.developAndImproveProducts // 10
];
return _hasConsent(info, list1) &&
_hasConsentOrLegitimateInterest(info, list2);
}
return true;
}
return null;
}
_hasConsentOrLegitimateInterest(
ConsentInfo info, List<DataUsagePurpose> purposes) {
return purposes.every((purpose) =>
info.publisherConsent.contains(purpose) ||
info.publisherLegitimateInterests.contains(purpose));
}
_hasConsent(ConsentInfo info, List<DataUsagePurpose> purposes) {
return purposes.every((purpose) => info.publisherConsent.contains(purpose));
}
Future<BasicConsentInfo?> _consentInfo() async {
return await IabtcfConsentInfo.instance.currentConsentInfo();
}
}