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

如何通过MethodChannel在Flutter中集成Kotlin版AdMob UMP合规代码

实现AdMob UMP合规逻辑的Flutter与Android原生交互方案

一、Android端(Kotlin)改造与MethodChannel配置

先修正你提供的混合Java语法的Kotlin代码,并添加MethodChannel实现:

import android.os.Bundle
import com.google.android.ump.*
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private lateinit var consentInformation: ConsentInformation
    private var consentForm: ConsentForm? = null
    private val CHANNEL = "com.example.ump_consent/channel" // 自定义通道名,需与Flutter端完全一致

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        // 注册MethodChannel,处理Flutter端调用请求
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "requestConsent" -> handleConsentRequest(result)
                else -> result.notImplemented()
            }
        }
    }

    private fun handleConsentRequest(result: MethodChannel.Result) {
        val debugSettings = ConsentDebugSettings.Builder(this)
            .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
            .build()

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

        consentInformation = UserMessagingPlatform.getConsentInformation(this)
        consentInformation.requestConsentInfoUpdate(
            this,
            params,
            object : ConsentInformation.OnConsentInfoUpdateSuccessListener {
                override fun onConsentInfoUpdateSuccess() {
                    if (consentInformation.isConsentFormAvailable()) {
                        loadForm(result)
                    } else {
                        initMobileAds()
                        result.success("无需展示合规表单")
                    }
                }
            },
            object : ConsentInformation.OnConsentInfoUpdateFailureListener {
                override fun onConsentInfoUpdateFailure(formError: FormError) {
                    initMobileAds()
                    result.error("CONSENT_ERROR", formError.message, null)
                }
            }
        )
    }

    private fun loadForm(result: MethodChannel.Result) {
        UserMessagingPlatform.loadConsentForm(
            this,
            object : UserMessagingPlatform.OnConsentFormLoadSuccessListener {
                override fun onConsentFormLoadSuccess(loadedForm: ConsentForm) {
                    consentForm = loadedForm
                    if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.REQUIRED) {
                        loadedForm.show(
                            this@MainActivity,
                            object : ConsentForm.OnConsentFormDismissedListener {
                                override fun onConsentFormDismissed(formError: FormError?) {
                                    if (consentInformation.consentStatus == ConsentInformation.ConsentStatus.OBTAINED) {
                                        initMobileAds()
                                        result.success("用户已同意合规协议")
                                    } else {
                                        initMobileAds()
                                        result.success("用户未同意合规协议")
                                    }
                                }
                            }
                        )
                    } else {
                        initMobileAds()
                        result.success("用户已完成合规授权")
                    }
                }
            },
            object : UserMessagingPlatform.OnConsentFormLoadFailureListener {
                override fun onConsentFormLoadFailure(formError: FormError) {
                    initMobileAds()
                    result.error("FORM_LOAD_ERROR", formError.message, null)
                }
            }
        )
    }

    private fun initMobileAds() {
        MobileAds.initialize(this) {
            // 广告初始化完成回调,可添加后续逻辑
        }
    }
}

二、Flutter端配置与调用

修改你的Flutter main 函数,添加MethodChannel调用逻辑,确保广告初始化前先完成合规请求:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化MethodChannel,通道名与Android端一致
  const MethodChannel channel = MethodChannel('com.example.ump_consent/channel');
  try {
    // 调用原生端的合规请求方法
    final String result = await channel.invokeMethod('requestConsent');
    print('合规请求结果: $result');
  } on PlatformException catch (e) {
    print('合规请求错误: ${e.message}');
  }
  
  // 广告初始化放在合规请求之后执行
  await MobileAds.instance.initialize();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'UMP合规集成Demo',
      home: Scaffold(
        appBar: AppBar(title: const Text('AdMob UMP合规')),
        body: const Center(child: Text('UMP合规集成完成')),
      ),
    );
  }
}

三、关键注意事项

  • 通道名一致性:Flutter和Android端的MethodChannel名称必须完全匹配,否则无法建立通信。
  • 主线程操作:UMP的表单加载、展示必须在Android主线程执行,Flutter的MethodChannel默认在主线程处理调用,无需额外切换线程。
  • 错误处理:原生端需通过result.error将异常信息返回给Flutter,方便前端捕获并处理异常场景。
  • 避免无限循环:移除了原代码中表单关闭后重复加载的逻辑,防止出现无限循环,可根据业务需求调整。
  • 依赖配置:确保Android项目build.gradle中已添加UMP依赖:
    dependencies {
        implementation 'com.google.android.ump:user-messaging-platform:2.2.0' // 替换为最新版本
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:28:20