Android、UMP,如何知道用户是否同意?

问题描述 投票:0回答:2

Android,即使用户不同意或用户关闭表单,UMP 也始终返回“OBTAINED”。 所以很难用它做任何事情。我想知道用户是否不同意,在这种情况下关闭应用程序。然后下次打开应用程序时,应该立即显示表单。然而,另一个问题是,当用户在表单中选择内容并批准同意时,下次再次打开表单时,设置将被重置(就像表单从未保存过一样)。另一个问题是,用户几乎不可能选择正确的内容来获取广告,并且在大多数情况下,用户将获得一个没有任何广告的免费应用程序(因为 OBTAINED 状态并不能说明用户是否同意)。另外,我无法获取用户选择的内容(我真的需要查看共享首选项才能获取该信息吗?总体而言,这个 UMP 似乎工作得很奇怪,或者也许我实现了错误?也许很快就会发布任何改进使用实现 'com.google.android.ump:user-messaging-platform:2.1.0'

此外,如果用户已经同意,并且 Admob 设置从我的应用程序的个人广告更改为非个人广告,那么用户仍然会收到个人广告。

这是代码:

ConsentRequestParameters params = new ConsentRequestParameters
                .Builder()
                .setTagForUnderAgeOfConsent(false)
                .build();

        ConsentInformation consentInformation;
        consentInformation = UserMessagingPlatform.getConsentInformation(this.getApplicationContext());
        consentInformation.requestConsentInfoUpdate(
                (Activity) this,
                params,
                new ConsentInformation.OnConsentInfoUpdateSuccessListener() {
                    @Override
                    public void onConsentInfoUpdateSuccess() {
                        // The consent information state was updated.
                        // You are now ready to check if a form is available.
                        if (consentInformation.isConsentFormAvailable()) {
                            // Loads a consent form. Must be called on the main thread.
                            UserMessagingPlatform.loadConsentForm(
                                    MyActivity.this.getApplicationContext(),
                                    new UserMessagingPlatform.OnConsentFormLoadSuccessListener() {
                                        @Override
                                        public void onConsentFormLoadSuccess(ConsentForm consentForm) {
                                            consentForm.show(
                                                    (Activity) MyActivity.this,
                                                    new ConsentForm.OnConsentFormDismissedListener() {
                                                        @Override
                                                        public void onConsentFormDismissed(@Nullable FormError formError) {
                                                            // TODO: Always getting "OBTAINED" even if user dismissed form or selected to not consent.
                                                            // User did not consent so consentStatus is still REQUIRED
                                                            if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.REQUIRED) {
                                                                MyActivity.this.finish();
                                                            }
                                                        }
                                                    });
                                        }
                                    },
                                    new UserMessagingPlatform.OnConsentFormLoadFailureListener() {
                                        @Override
                                        public void onConsentFormLoadFailure(FormError formError) {
                                            // Handle Error.
                                        }
                                    }
                            );
                        } else {
                            // Handle error
                        }
                    }
                },
                new ConsentInformation.OnConsentInfoUpdateFailureListener() {
                    @Override
                    public void onConsentInfoUpdateFailure(FormError formError) {
                        // Handle the error.
                    }
                });

我尝试过以各种方式更改代码,但仍然遇到相同的问题。所以现在我在 Admob 设置中选择了非个人广告,因为 UMP 似乎不起作用。

android admob sharedpreferences ads ump
2个回答
5
投票

在 Google 一周毫无进展之后...他们的哲学似乎是故意将 AdMob 变成垃圾箱大火(不同意“合法利益”不是问题!)...我已经决定了我的临时解决方案,直到他们希望有一天能够齐心协力。

总之我是...

  1. 向用户呈现官方谷歌同意屏幕
  2. 使用iabtcf_consent_info包来检索他们的响应
  3. 通过自定义解析器类传递这些响应,该解析器类将它们的响应转换为我们真正关心的信息“无广告、非目标广告、目标广告”
  4. 通过流输出该摘要
  5. 如果该流输出“无广告”,则禁用对某些功能的访问

如果流输出“无广告”,那么当他们到达主页时,我会向他们显示一个对话框,解释为什么某些功能被禁用并邀请他们重新提交同意选项。

这当然是一种可怕的用户体验...输入一堆神秘的同意选项只是在主页上被拒绝并被告知再次这样做,因为他们选择的组合是错误的...但这似乎就是用户体验谷歌想要。

要么他们认真地期望我们支持不同意用户的费用,而没有任何手段将他们货币化!

以下是我的解析器类,以防有人想遵循类似的方法(我是一名 flutter 开发人员,但我知道 dart 与 JavaScript 没有什么不同)。

import 'dart:async';
import 'package:buck_the_critics/enums.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:iabtcf_consent_info/iabtcf_consent_info.dart';
class AdmobConsentParser {
  // User must consent to these for any ads at all
  List < DataUsagePurpose > consentsRequiredForAds = [
    DataUsagePurpose.storeAndAccessInformationOnADevice // 1
  ];
  // User must consent to these for targetted ads
  List < DataUsagePurpose > consentsRequiredForTargettedAds = [
    DataUsagePurpose.storeAndAccessInformationOnADevice, // 1
    DataUsagePurpose.createAPersonalisedAdsProfile, // 3
    DataUsagePurpose.selectPersonalisedAds, // 4
  ];
  // User must either consent or NOT untoggle legitimate interest for any of these for any ads at all
  List < DataUsagePurpose > usagesRequiringConsentOrLegitimateInterest = [
    DataUsagePurpose.selectBasicAds, // 2
    DataUsagePurpose.measureAdPerformance, // 7
    DataUsagePurpose.applyMarketResearchToGenerateAudienceInsights, // 9
    DataUsagePurpose.developAndImproveProducts // 10
  ];
  Future < AdConsent > getAdConsentLevel(BasicConsentInfo ? usersConsent) async {
    if (usersConsent != null && usersConsent is ConsentInfo) {
      final gdprApplies = isGDPR(usersConsent);
      if (gdprApplies == true) {
        final targetedAds = await canShowPersonalizedAds(usersConsent);
        if (targetedAds != null && targetedAds) {
          return AdConsent.targeted;
        } else {
          final untargetedAds = await canShowAds(usersConsent);
          if (untargetedAds != null && untargetedAds) {
            return AdConsent.untargeted;
          } else {
            return AdConsent.none;
          }
        }
      } else {
        return AdConsent.none;
      }
    } else {
      return AdConsent.targeted;
    }
  }
  bool ? isGDPR(BasicConsentInfo ? usersConsent) {
    return usersConsent ? .gdprApplies;
  }
  // 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
  Future < bool ? > canShowAds(ConsentInfo usersConsent) async {
    final hasConsent = _hasConsent(usersConsent, consentsRequiredForAds);
    final hasConsentOrLegitimateInterest = _hasConsentOrLegitimateInterest(
      usersConsent, usagesRequiringConsentOrLegitimateInterest);
    return hasConsent && hasConsentOrLegitimateInterest;
  }
  // 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
  Future < bool ? > canShowPersonalizedAds(ConsentInfo usersConsent) async {
    return _hasConsent(usersConsent, consentsRequiredForTargettedAds) &&
      _hasConsentOrLegitimateInterest(
        usersConsent, usagesRequiringConsentOrLegitimateInterest);
  }
  _hasConsent(
    ConsentInfo usersConsent, List < DataUsagePurpose > requiredConsents) {
    return requiredConsents
      .every((purpose) => usersConsent.purposeConsents.contains(purpose));
  }
  _hasConsentOrLegitimateInterest(ConsentInfo usersConsent,
    List < DataUsagePurpose > requiredLegitimateInterests) {
    return requiredLegitimateInterests.every((purpose) =>
      usersConsent.purposeConsents.contains(purpose) ||
      usersConsent.purposeLegitimateInterests.contains(purpose));
  }
}
final admobConsentParserProvider = Provider.autoDispose((ref) {
  return AdmobConsentParser();
});
final adConsentLevelProvider = StreamProvider.autoDispose < AdConsent > ((ref) {
  final controller = StreamController < AdConsent > ();
  final consentParser = ref.watch(admobConsentParserProvider);
  IabtcfConsentInfo.instance.consentInfo().listen((event) async {
    final consentLevel = await consentParser.getAdConsentLevel(event);
    controller.sink.add(consentLevel);
  });
  return controller.stream;
});


0
投票

import 'dart:async';
import 'package:buck_the_critics/enums.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:iabtcf_consent_info/iabtcf_consent_info.dart';
class AdmobConsentParser {
  // User must consent to these for any ads at all
  List < DataUsagePurpose > consentsRequiredForAds = [
    DataUsagePurpose.storeAndAccessInformationOnADevice // 1
  ];
  // User must consent to these for targetted ads
  List < DataUsagePurpose > consentsRequiredForTargettedAds = [
    DataUsagePurpose.storeAndAccessInformationOnADevice, // 1
    DataUsagePurpose.createAPersonalisedAdsProfile, // 3
    DataUsagePurpose.selectPersonalisedAds, // 4
  ];
  // User must either consent or NOT untoggle legitimate interest for any of these for any ads at all
  List < DataUsagePurpose > usagesRequiringConsentOrLegitimateInterest = [
    DataUsagePurpose.selectBasicAds, // 2
    DataUsagePurpose.measureAdPerformance, // 7
    DataUsagePurpose.applyMarketResearchToGenerateAudienceInsights, // 9
    DataUsagePurpose.developAndImproveProducts // 10
  ];
  Future < AdConsent > getAdConsentLevel(BasicConsentInfo ? usersConsent) async {
    if (usersConsent != null && usersConsent is ConsentInfo) {
      final gdprApplies = isGDPR(usersConsent);
      if (gdprApplies == true) {
        final targetedAds = await canShowPersonalizedAds(usersConsent);
        if (targetedAds != null && targetedAds) {
          return AdConsent.targeted;
        } else {
          final untargetedAds = await canShowAds(usersConsent);
          if (untargetedAds != null && untargetedAds) {
            return AdConsent.untargeted;
          } else {
            return AdConsent.none;
          }
        }
      } else {
        return AdConsent.none;
      }
    } else {
      return AdConsent.targeted;
    }
  }
  bool ? isGDPR(BasicConsentInfo ? usersConsent) {
    return usersConsent ? .gdprApplies;
  }
  // 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
  Future < bool ? > canShowAds(ConsentInfo usersConsent) async {
    final hasConsent = _hasConsent(usersConsent, consentsRequiredForAds);
    final hasConsentOrLegitimateInterest = _hasConsentOrLegitimateInterest(
      usersConsent, usagesRequiringConsentOrLegitimateInterest);
    return hasConsent && hasConsentOrLegitimateInterest;
  }
  // 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
  Future < bool ? > canShowPersonalizedAds(ConsentInfo usersConsent) async {
    return _hasConsent(usersConsent, consentsRequiredForTargettedAds) &&
      _hasConsentOrLegitimateInterest(
        usersConsent, usagesRequiringConsentOrLegitimateInterest);
  }
  _hasConsent(
    ConsentInfo usersConsent, List < DataUsagePurpose > requiredConsents) {
    return requiredConsents
      .every((purpose) => usersConsent.purposeConsents.contains(purpose));
  }
  _hasConsentOrLegitimateInterest(ConsentInfo usersConsent,
    List < DataUsagePurpose > requiredLegitimateInterests) {
    return requiredLegitimateInterests.every((purpose) =>
      usersConsent.purposeConsents.contains(purpose) ||
      usersConsent.purposeLegitimateInterests.contains(purpose));
  }
}
final admobConsentParserProvider = Provider.autoDispose((ref) {
  return AdmobConsentParser();
});
final adConsentLevelProvider = StreamProvider.autoDispose < AdConsent > ((ref) {
  final controller = StreamController < AdConsent > ();
  final consentParser = ref.watch(admobConsentParserProvider);
  IabtcfConsentInfo.instance.consentInfo().listen((event) async {
    final consentLevel = await consentParser.getAdConsentLevel(event);
    controller.sink.add(consentLevel);
  });
  return controller.stream;
});

© www.soinside.com 2019 - 2024. All rights reserved.