Skip to content

ConsentManager 继承自: ft.Service, BaseControl

使用 Google 的用户消息平台(UMP)收集并管理用户对广告的同意。

使用此服务来请求同意信息、展示同意表单(例如 GDPR/EEA 同意对话框)与隐私选项表单, 并在请求广告之前查询同意状态。

典型流程如下:

  1. request_consent_info_update(每次启动应用时);
  2. load_and_show_consent_form_if_required(仅在需要时才展示表单);
  3. can_request_ads(用于决定是否开始加载广告)。

更多信息见 AdMob 文档。

抛出异常: FletUnsupportedPlatformException:在 Web 和/或非移动端平台上使用时抛出。

示例 ​

python
import flet as ft
import flet_ads as fta


def main(page: ft.Page):
    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER

    # mobile-only
    supported = not page.web and page.platform.is_mobile()
    if supported:
        page.services.append(consent_manager := fta.ConsentManager())

    async def refresh_status():
        consent_status = await consent_manager.get_consent_status()
        privacy_status = await consent_manager.get_privacy_options_requirement_status()
        can_request = await consent_manager.can_request_ads()
        status.value = (
            f"Consent status: {consent_status.name}\n"
            f"Privacy options required: {privacy_status.name}\n"
            f"Can request ads: {can_request}"
        )
        # Only surface the privacy options entry point when we are required to.
        privacy_button.visible = (
            privacy_status == fta.PrivacyOptionsRequirementStatus.REQUIRED
        )
        page.update()

    async def gather_consent(e: ft.Event[ft.OutlinedButton]):
        status.value = "Gathering consent…"
        status.update()
        try:
            # Remember to remove the debug settings in production.
            await consent_manager.request_consent_info_update(
                fta.ConsentRequestParameters(
                    consent_debug_settings=fta.ConsentDebugSettings(
                        debug_geography=fta.DebugGeography.EEA,
                        # test_identifiers=["<HASHED_ID>"], # for physical devices only
                    ),
                )
            )
            # Loads and shows the consent form only if consent is required.
            await consent_manager.load_and_show_consent_form_if_required()
            await refresh_status()
            # At this point, if `can_request_ads()` is True, it is safe to start
            # loading ads (e.g. fta.BannerAd / fta.InterstitialAd).
        except Exception as ex:
            status.value = f"Error: {ex}"
            status.update()

    async def show_privacy_options(e: ft.Event[ft.OutlinedButton]):
        try:
            await consent_manager.show_privacy_options_form()
            await refresh_status()
        except Exception as ex:
            status.value = f"Error: {ex}"
        page.update()

    async def reset_consent(e: ft.Event[ft.OutlinedButton]):
        # For testing only: resets consent so you can replay the flow.
        try:
            await consent_manager.reset()
            status.value = 'Consent reset. Tap "Gather consent" to begin again.'
            privacy_button.visible = False
        except Exception as ex:
            status.value = f"Error: {ex}"
        page.update()

    page.add(
        ft.SafeArea(
            content=ft.Column(
                horizontal_alignment=ft.CrossAxisAlignment.CENTER,
                controls=[
                    ft.Text(
                        "Gather user consent (e.g. GDPR/EEA) with Google's User "
                        "Messaging Platform before requesting ads.",
                        text_align=ft.TextAlign.CENTER,
                    ),
                    ft.OutlinedButton(
                        content="Gather consent",
                        on_click=gather_consent,
                        disabled=not supported,
                    ),
                    privacy_button := ft.OutlinedButton(
                        content="Show privacy options form",
                        visible=False,
                        on_click=show_privacy_options,
                    ),
                    ft.OutlinedButton(
                        content="Reset consent (testing)",
                        on_click=reset_consent,
                        disabled=not supported,
                    ),
                    ft.Divider(),
                    status := ft.Text('Tap "Gather consent" to begin.'),
                ],
            )
        ),
    )


if __name__ == "__main__":
    ft.run(main)

属性 ​

名称类型默认值说明
dataAnyskip_任意类型的自定义数据。
keyOptional['KeyValue']None用于在更新之间保持控件身份稳定的 key。

只读属性 ​

名称类型默认值说明
parentOptional['BaseControl']—The direct ancestor(parent) of this control. It defaults to None and will only have a value when this control is mounted (added to the page tree). Page 控件(树的根)为例外 —— 它始终 parent=None。
page'Page'—此控件所属的页面。

方法 ​

名称类型默认值说明
before_update———
request_consent_info_update——Requests an update of the user's consent information. This should be called (and awaited) at every app launch, before loading/showing a consent form or reading the consent status. Args: params: Parameters such as debug settings (useful for testing the form during development) or the under-age tag. If None, default parameters are used.
is_consent_form_availablebool—Checks whether a consent form is available to be loaded and shown. Note: request_consent_info_update should be awaited before calling this method. Returns: True if a consent form is available, False otherwise.
get_consent_statusConsentStatus—Get the user’s consent status. This value is cached between app sessions and can be read before requesting an update of the consent information. Returns: The user's current consent status.
can_request_adsbool—Indicates whether the app has gathered enough consent to request ads. Returns: True if ads can be requested, False otherwise.
get_privacy_options_requirement_statusPrivacyOptionsRequirementStatus—Gets the requirement status for showing a privacy options entry point. Returns: Whether a privacy options entry point (for example, a button that calls show_privacy_options_form) is required.
load_and_show_consent_form_if_required——Loads a consent form and immediately shows it if consent is required. If consent is not required, this method completes without showing anything. This is the simplest way to gather consent: call request_consent_info_update first, then this method.
show_privacy_options_form——Presents the privacy options form to the user. This lets users change or withdraw their consent after the initial choice. Only present it when get_privacy_options_requirement_status returns REQUIRED.
reset——Resets the consent state. Warning: This is intended only for testing, allowing you to simulate a first-time user. It should not be used in production.
init———
is_isolated——Return whether this control is marked as isolated. 被隔离的控件不会参与父级驱动的更新遍历,需要自行管理更新边界。
build——在控件初始化期间调用一次,用于定义其子控件。 page 属性在此方法中可用。
before_event——在事件处理器执行前拦截事件。 返回 False 取消分发,返回 True 或 None 则继续正常的事件处理。
did_mount——在控件挂载到页面树之后调用。 可重写以启动需要已挂载页面的资源,例如订阅、定时器或服务监听。
will_unmount——在控件从页面树移除之前调用。 可重写以释放 did_mount() 中创建的资源,例如订阅、定时器或外部句柄。
get_data_channel——Resolve the [DataChannel] allocated on the Dart side for this widget. Pattern: on_data_channel_open: Optional[ft.EventHandler[DataChannelOpenEvent]] = None def init(self): self.on_data_channel_open = self._on_open def _on_open(self, e): self._channel = self.get_data_channel(e.channel_id) Idempotent — the underlying Connection caches DataChannels by id, so repeated calls return the same instance. No error path: the id always comes from a framework-fired event, so by the time this runs the channel exists on both sides.
updateNone—请求更新该控件的 UI。 在修改控件状态或属性后调用。 控件必须已挂载到页面,并且未被冻结。

关注我,学习大模型、大数据、Python等热门技术。