You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AdMob集成UMP SDK遇TCF 10.1错误及美国州隐私消息不显示

处理AdMob+UMP SDK集成的两个核心问题

背景

我正在Android应用中集成Google AdMob + UMP SDK,用于处理GDPR及美国州级隐私要求(如加州CCPA、弗吉尼亚州等),实现逻辑参考官方规范。

问题1:TCF 10.1政策违规

已完整集成UMP SDK并向用户展示同意表单,但AdMob控制台「拦截控制->欧盟用户同意」中仍显示“TCF Error 10.1”,说明未收到符合TCF标准的信号。SDK仅在获取同意后初始化,且已正确检查canRequestAds()。

问题2:CCPA/美国州级隐私消息未展示

已在AdMob控制台创建美国州隐私消息,配置为"Don't restrict data processing",但大量美国用户从未看到该消息,控制台数据显示:

Messages shown: 0  
Opt-out selections: 0

依赖项配置

implementation 'com.google.android.gms:play-services-ads:24.2.0'
implementation 'com.google.android.ump:user-messaging-platform:3.2.0'
implementation platform('com.google.firebase:firebase-bom:33.9.0')
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.google.firebase:firebase-analytics'

核心代码实现

ConsentManager类

public class GoogleMobileAdsConsentManager {
    private static GoogleMobileAdsConsentManager instance;
    private final ConsentInformation consentInformation;

    private GoogleMobileAdsConsentManager(Context context) {
        this.consentInformation = UserMessagingPlatform.getConsentInformation(context);
    }

    public static GoogleMobileAdsConsentManager getInstance(Context context) {
        if (instance == null) {
            instance = new GoogleMobileAdsConsentManager(context);
        }
        return instance;
    }

    public interface OnConsentGatheringCompleteListener {
        void consentGatheringComplete(FormError error);
    }

    public boolean canRequestAds() {
        return consentInformation.canRequestAds();
    }

    public boolean isPrivacyOptionsRequired() {
        return consentInformation.getPrivacyOptionsRequirementStatus()
                == ConsentInformation.PrivacyOptionsRequirementStatus.REQUIRED;
    }

    public void gatherConsent(Activity activity, OnConsentGatheringCompleteListener listener) {
        ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(activity)
                // .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
                // .addTestDeviceHashedId("YOUR_TEST_DEVICE_HASHED_ID")
                .build();

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

        consentInformation.requestConsentInfoUpdate(
                activity,
                params,
                () -> loadAndShowConsentFormIfRequired(activity, listener),
                listener::consentGatheringComplete
        );
    }

    private void loadAndShowConsentFormIfRequired(Activity activity,
                                                  OnConsentGatheringCompleteListener listener) {
        UserMessagingPlatform.loadAndShowConsentFormIfRequired(activity, listener::consentGatheringComplete);
    }

    public void showPrivacyOptionsForm(Activity activity, ConsentForm.OnConsentFormDismissedListener listener) {
        UserMessagingPlatform.showPrivacyOptionsForm(activity, listener);
    }
}

Activity中调用逻辑

GoogleMobileAdsConsentManager.getInstance(this)
    .gatherConsent(this, error -> {
        if (GoogleMobileAdsConsentManager.getInstance(this).canRequestAds()) {
            MobileAds.initialize(this, initializationStatus -> {
                loadEnterInterstitial();
            });
        }
    });

插屏广告加载代码

private void loadEnterInterstitial() {
    if (isAdLoading || mEnterInterstitial != null) return;
    isAdLoading = true;

    String unitId = shared.getString("admob_inter_open_unit", "");
    boolean enabled = shared.getBoolean("admob_enter_full", false);

    if (!enabled || unitId.isEmpty()) {
        isAdLoading = false;
        return;
    }

    AdRequest request = new AdRequest.Builder().build();
    InterstitialAd.load(
        this,
        unitId,
        request,
        new InterstitialAdLoadCallback() {
            @Override
            public void onAdLoaded(@NonNull InterstitialAd ad) {
                mEnterInterstitial = ad;
                isAdLoading = false;

                mEnterInterstitial.setFullScreenContentCallback(new FullScreenContentCallback() {
                    @Override
                    public void onAdDismissedFullScreenContent() {
                        mEnterInterstitial = null;
                    }
                    @Override
                    public void onAdFailedToShowFullScreenContent(AdError adError) {
                        mEnterInterstitial = null;
                    }
                });
            }

            @Override
            public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                Log.w("MainActivity", "Enter Interstitial load failed: " + loadAdError.getMessage());
                mEnterInterstitial = null;
                isAdLoading = false;
            }
        }
    );
}

已排查内容

  • 已向EEA用户展示同意表单
  • 仅在canRequestAds()返回true时请求广告
  • UMP SDK使用最新版本
  • AdMob控制台已正确配置CCPA消息并选择对应州,设置为"Don't restrict data processing"
  • 生产环境已集成Firebase SDK

问题解答

针对TCF 10.1错误的排查方向

  1. 确认TCF表单配置完整性:检查AdMob控制台「欧盟用户同意」设置,确保已启用TCF模式,且关联的广告技术提供商列表完整。未正确启用TCF会导致UMP无法生成合规信号。
  2. 验证同意信号传递:通过consentInformation.getTCData()方法检查是否获取到有效TCF字符串,确保同意数据已同步到AdMob SDK。
  3. 清除旧缓存:用户设备上的旧同意缓存可能导致信号异常,测试时调用consentInformation.reset()清除缓存,重新触发同意流程验证。
  4. 严格控制初始化时机:确保requestConsentInfoUpdate()回调完全执行后,再初始化AdMob SDK,避免因初始化过早导致同意信号未注入广告请求。

针对美国州级隐私消息未展示的排查方向

  1. 检查位置权限:UMP依赖设备地理信息判断用户所在州,需确保应用已申请ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限,且用户已授权。
  2. 确认控制台配置:检查AdMob控制台中美国州隐私消息的目标州是否覆盖用户所在州,且消息状态为「已发布」而非「草稿」。
  3. 清除用户缓存:若用户之前已做出隐私选择,UMP会缓存结果不再展示消息,可调用consentInformation.reset()清除缓存测试新用户流程。
  4. 测试环境强制触发:使用测试设备时,通过ConsentDebugSettings设置DEBUG_GEOGRAPHY_USA并添加测试设备ID,强制展示美国州隐私消息验证逻辑。

内容的提问来源于stack exchange,提问作者Shayegan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:14:51