向 Flutter 应用添加 AdMob 广告

构建内容

此 Codelab 将指导您向一款名为 Awesome Drawing Quiz(一款让玩家猜测图画中对象名字的游戏)的应用添加 AdMob 横幅广告、插页式广告和激励广告。

如果您在学习本 Codelab 时遇到任何问题(代码错误、语法错误、措辞含义不明等),欢迎通过 Codelab 左下角的报告错误链接向我们报告相应问题。

学习内容

  • 如何为 Flutter 应用设置 Firebase 项目
  • 如何配置 Firebase AdMob 插件
  • 如何在 Flutter 应用中使用横幅广告、插页式广告和激励广告

所需条件

  • Android Studio 3.6 或更高版本
  • Xcode(用于支持 iOS)

您如何评价自己在 AdMob 方面的经验水平?

新手水平 中等水平 熟练水平

您想通过此 Codelab 学习什么?

我不熟悉这个主题,想深入了解一下。 我对这个主题有所了解,但我想重温一下。 我在寻找示例代码以用到我的项目中。 我在寻找有关特定内容的说明。

设置 Flutter 开发环境

  1. 按照 flutter.dev 中的安装说明,在计算机上安装 Flutter SDK。
  2. 打开 Android Studio,然后按照配置页面中的步骤为 Android Studio 安装 Flutter 和 Dart 插件。

下载代码

如需将此 Codelab 的所有代码下载为 ZIP 文件,请点击以下按钮:

下载源代码

提取 ZIP 文件中的文件。该操作将解压缩名为 admob-ads-in-flutter-master 的根文件夹。

或者,您也可以从命令行克隆相应 GitHub 代码库。

$ git clone https://github.com/googlecodelabs/admob-ads-in-flutter

该代码库包含两个文件夹:

  • android_studio_folder.pngstarter — 用于构建此 Codelab 的起始代码。
  • android_studio_folder.pngcomplete:此 Codelab 完成后的代码。

导入 starter 项目

  1. 打开 Android Studio。
  2. 在欢迎屏幕上,选择 Open an existing Android Studio projecta3a1fa1afc967e37.png
  3. 打开您在上一步骤中下载的代码中的 android_studio_folder.pngstarter 文件夹。

a879fa2385ba368f.png

  1. 您可能会在 Dart Analysis 标签页中看到以下错误消息。该错误仅会在您将现有项目导入 Android Studio 时发生一次,这是因为示例项目中使用的软件包尚未下载。

2b8fbccf84e1e8a5.png

  1. 如需修正该错误,请点击编辑器窗格顶部的 Get dependencies。该操作会下载示例项目所依赖的软件包。

dc017166e44ac333.png

  1. 下载完成后,您在 Dart Analysis 标签页中应该不会再看到任何错误。现在,您的项目已做好开发准备。

您需要设置一个 Firebase 项目,以便使用 Firebase AdMob 插件来投放 AdMob 广告。

创建 Firebase 项目

  1. Firebase 控制台中,点击添加项目
  2. 输入 Awesome Drawing Quiz 作为项目名称。
  3. 为您的项目启用 Google Analytics(分析),然后点击继续

87590d75b00db648.png

  1. 选择适用于您的项目的分析位置和设置。阅读并接受相关条款,然后点击创建项目

700c64d82fedbd0b.png

  1. 大约一分钟后,您的 Firebase 项目就准备就绪了。

向 Firebase 注册该应用

Firebase 控制台中,选择您在上一步中创建的 Awesome Drawing Quizer 项目。

注册 Android 应用

  1. 在项目概览页面的中心位置,点击 Android 图标以启动设置工作流。
  2. Android 软件包名称字段中输入 com.codelab.awesomedrawingquiz
  3. 应用别名字段中输入 Awesome Drawing Quiz (Android)
  4. 点击注册应用
  5. 下载 google-services.json 文件以供日后使用。

注册 iOS 应用

  1. 在项目概览页面的中心位置,点击 iOS 图标添加应用 (+) 图标以启动设置工作流。
  2. iOS 软件包 ID 字段中输入 com.codelab.awesomedrawingquiz
  3. 应用别名字段中输入 Awesome Drawing Quiz (iOS)
  4. 点击注册应用
  5. 下载 GoogleService-Info.plist 文件以供日后使用。

添加 Firebase 配置文件

以下说明介绍了如何针对 Android 和 iOS 配置 Firebase。

针对 Android 进行配置

  1. 按照此 Codelab 的设置开发环境步骤中的导入 starter 项目部分的说明,在 Android Studio 中打开 starter 项目。
  2. google-services.json 文件移动到 Awesome Drawing Quizer Flutter 项目的 android/app 目录中。

bd0729c424b0c79d.png

  1. 在根级(项目级)Gradle 文件 (android/build.gradle) 中添加规则,以包含 Google 服务 Gradle 插件。检查您是否有 Google 的 Maven 代码库。

android/build.gradle

buildscript {

    repositories {
      // Check that you have the following line (if not, add it):
      google()  // Google's Maven repository
    }

    ...

    dependencies {
      ...

      // TODO: Add Google Services plugin
      classpath 'com.google.gms:google-services:4.3.3'
    }
}

allprojects {
    ...

    repositories {
      // Check that you have the following line (if not, add it):
      google()  // Google's Maven repository
      ...
    }
}
  1. 在模块(应用级)Gradle 文件 (android/app/build.gradle) 中,应用 Google 服务 Gradle 插件。

android/app/build.gradle

...

// TODO: Apply google-services plugin
apply plugin: 'com.google.gms.google-services'

android {
  ...
}

...

针对 iOS 进行配置

  1. 按照此 Codelab 的设置开发环境步骤中的导入 starter 项目部分的说明,在 Android Studio 中打开 starter 项目。
  2. 打开 ios 目录下的任何文件。(例如 ios/Runner/AppDelegate.swift
  3. 点击 Open iOS module in Xcode

b0e50d31ada7bf46.png

  1. 在 Xcode 中,将 GoogleService-Info.plist 文件拖动到 Runner 目录中,以将配置文件导入 Xcode 项目中。

1f552ff12b67008.png

由于 Flutter 是一个多平台 SDK,因此您需要在 AdMob 中同时添加适用于 Android 和 iOS 的应用和广告单元。

在开始之前,您应先熟悉以下 AdMob 术语表。

广告单元

广告单元是指在一段 AdMob 广告代码的作用下显示的一组广告。您可以在 AdMob 帐号中创建和自定义广告单元。

每个广告单元都有一个唯一标识符,称为广告单元 ID。在该应用中实现新广告单元时,您需要引用广告单元 ID,以告知广告联盟在收到请求后将广告发送到什么位置。

横幅广告

横幅广告会占据应用布局中的一处位置,要么是设备屏幕的顶部,要么是底部。这类广告会在用户与应用互动时停留在屏幕上,并且可在一段时间后自动刷新。

插页式广告

插页式广告属于全屏广告,会覆盖宿主应用的整个界面,通常展示在应用流程的自然过渡点上,例如,活动之间的切换处或游戏关卡之间的暂停时段中。

激励广告

所谓激励广告,指的是用户可以选择与之互动来换取应用内奖励的一种广告。

针对 Android 进行设置

此部分将向您介绍如何向 AdMob 添加 Android 应用和广告单元。

添加 Android 应用

请按以下说明向 AdMob 添加 Android 应用:

  1. AdMob 控制台中,点击应用菜单中的添加应用
  2. 当系统询问“您是否已在 Google Play 或 App Store 中发布您的应用?”时,点击
  3. 应用名称字段中输入 Awesome Drawing Quiz,然后选择 Android 作为平台。

152e1694fd0ce870.png

  1. 您不必启用用户指标就能完成此 Codelab。不过,我们建议您启用用户指标,因为启用后即可提供包含详细用户行为的分析数据。点击添加以完成该流程。

5204925f5c652b41.png

  1. 记下新应用的 ID (ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy)。您需要将该 ID 添加到示例项目的源代码,以便投放广告。

创建广告单元

如需开始向 AdMob 添加广告单元,请按以下步骤操作:

  1. AdMob 控制台应用菜单中选择 Awesome Drawing Quiz (Android)
  2. 点击广告单元菜单。

广告单元菜单中,按说明创建横幅广告单元、插页式广告单元和激励广告单元。

横幅广告

  1. 点击添加广告单元按钮。
  2. 选择横幅广告作为格式。
  3. 广告单元名称字段中输入 android-adq-banner
  4. 点击创建广告单元以完成该流程。

插页式广告

  1. 点击添加广告单元按钮。
  2. 选择插页式广告格式。
  3. 广告单元名称字段中输入 android-adq-interstitial
  4. 点击创建广告单元以完成该流程。

激励广告

  1. 点击添加广告单元按钮。
  2. 选择激励广告作为格式。
  3. 广告单元名称字段中输入 android-adq-rewarded
  4. 保留奖励设置的默认值。
  5. 点击创建广告单元以完成该流程。

针对 iOS 进行设置

此部分将向您介绍如何向 AdMob 添加 iOS 应用和广告单元。

添加 iOS 应用

请按以下说明向 AdMob 添加 iOS 应用:

  1. AdMob 控制台中,点击应用菜单中的添加应用
  2. 当系统询问“您是否已在 Google Play 或 App Store 中发布您的应用?”时,点击
  3. 应用名称字段中输入 Awesome Drawing Quiz,然后选择 iOS 作为平台。

a8fa48af652021d8.png

  1. 完成此 Codelab 并不一定要启用用户指标。不过,我们建议您启用用户指标,因为启用后即可提供包含详细用户行为的分析数据。点击添加以完成该流程。

5204925f5c652b41.png

  1. 记下新应用的 ID (ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy)。您需要将该 ID 添加到示例项目的源代码,以便投放广告。

创建广告单元

如需开始添加广告单元,请按以下步骤操作:

  1. AdMob 控制台应用菜单中选择 Awesome Drawing Quiz (iOS)
  2. 点击广告单元菜单。

广告单元菜单中,按说明创建横幅广告单元、插页式广告单元和激励广告单元。

横幅广告

  1. 点击添加广告单元按钮。
  2. 选择横幅广告作为格式。
  3. 广告单元名称字段中输入 ios-adq-banner
  4. 点击创建广告单元以完成该流程。

插页式广告

  1. 点击添加广告单元按钮。
  2. 选择插页式广告格式。
  3. 广告单元名称字段中输入 ios-adq-interstitial
  4. 点击创建广告单元以完成该流程。

激励广告

  1. 点击添加广告单元按钮。
  2. 选择激励广告作为格式。
  3. 广告单元名称字段中输入 ios-adq-rewarded
  4. 保留奖励设置的默认值。
  5. 点击创建广告单元以完成该流程。

使用预配置的 AdMob 应用和广告单元(可选)

如果您希望按照此 Codelab 操作,而不是自行创建新的应用和广告单元,您可以改用为此 Codelab 准备的下列 AdMob 应用 ID 和广告单元 ID。

Android

针对 Android 测试 AdMob ID:

项目

应用 ID/广告单元 ID

AdMob 应用 ID

ca-app-pub-3940256099942544~4354546703

横幅广告

ca-app-pub-3940256099942544/8865242552

插页式广告

ca-app-pub-3940256099942544/7049598008

激励广告

ca-app-pub-3940256099942544/8673189370

iOS

针对 iOS 测试 AdMob ID:

项目

应用 ID/广告单元 ID

AdMob 应用 ID

ca-app-pub-3940256099942544~2594085930

横幅广告

ca-app-pub-3940256099942544/4339318960

插页式广告

ca-app-pub-3940256099942544/3964253750

激励广告

ca-app-pub-3940256099942544/7552160883

Flutter 使用插件提供对各类平台专用服务的访问权限。插件包含平台专用代码,用于访问各种平台上的服务和 API。

firebase_admob 插件支持使用 AdMob API 加载和展示横幅广告、插页式广告和激励广告。

由于 Flutter 是一个多平台 SDK,因此 firebase_admob 插件既适用于 iOS,也适用于 Android。因此,如果您将该插件添加到 Flutter 应用,Android 和 iOS 版本的 Awesome Drawing Quizer 应用都会使用该插件。

添加 Firebase AdMob 插件作为依赖项

如需从 Awesome Drawing Quizer 项目访问 AdMob API,请将 firebase_admob 插件作为依赖项添加到位于项目根目录中的 pubspec.yaml 文件。

pubspec.yaml

...

dependencies:
  flutter:
    sdk: flutter
  google_fonts: ^0.3.9

  # Add the following line
  firebase_admob: ^0.9.3

...

点击 Packages get,将该插件安装到 Awesome Drawing Quizer 项目中。

d9fc62bf4054cea9.png

更新 AndroidManifest.xml (Android)

  1. 在 Android Studio 中打开 android/app/src/main/AndroidManifest.xml 文件。
  2. 添加 <meta-data> 代码并输入 com.google.android.gms.ads.APPLICATION_ID,以便添加您的 AdMob 应用 ID。如果您的 AdMob 应用 ID 为 ca-app-pub-3940256099942544~3347511713,则需要将以下代码行添加到 AndroidManifest.xml 文件。

android/app/src/main/AndroidManifest.xml

<manifest>
    ...
    <application>
       ...
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>
    </application>

</manifest>

更新 Info.plist (iOS)

  1. 在 Android Studio 中打开 ios/Runner/Info.plist 文件。
  2. 添加一个 GADApplicationIdentifier 键,并将 AdMob 应用 ID 设为相应字符串值。例如,如果您的 AdMob 应用 ID 为 ca-app-pub-3940256099942544~1458002511,则需要将以下代码行添加到 Info.plist 文件。

ios/Runner/Info.plist

...
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
...

lib 目录下创建一个名为 ad_manager.dart 的新文件。然后,实现 AdManager 类,该类会提供适用于 Android 和 iOS 的 AdMob 应用 ID 和广告单元 ID。

请务必将 AdMob 应用 ID (ca-app-pub-xxxxxx~yyyyy) 和广告单元 ID (ca-app-pub-xxxxxxx/yyyyyyyy) 替换为您在上一步骤中创建的 ID。

lib/ad_manager.dart

import 'dart:io';

class AdManager {

  static String get appId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_ADMOB_APP_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_ADMOB_APP_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_BANNER_AD_UNIT_ID";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_BANNER_AD_UNIT_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get interstitialAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_INTERSTITIAL_AD_UNIT_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_INTERSTITIAL_AD_UNIT_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get rewardedAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_REWARDED_AD_UNIT_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_REWARDED_AD_UNIT_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }
}

如果您想使用为此 Codelab 预配置的 AdMob 应用 ID 和广告单元 ID,请使用以下代码段。

lib/ad_manager.dart

import 'dart:io';

class AdManager {

  static String get appId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544~4354546703";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544~2594085930";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544/8865242552";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544/4339318960";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get interstitialAdUnitId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544/7049598008";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544/3964253750";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get rewardedAdUnitId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544/8673189370";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544/7552160883";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }
}

加载广告之前,您需要初始化 AdMob SDK。打开 lib/home_route.dart 文件,然后修改 _initAdMob() 以在游戏开始前初始化 SDK。

lib/home_route.dart

// TODO: Import ad_manager.dart
import 'package:awesome_drawing_quiz/ad_manager.dart';

import 'package:awesome_drawing_quiz/app_theme.dart';

// TODO: Import firebase_admob.dart
import 'package:firebase_admob/firebase_admob.dart';

import 'package:flutter/material.dart';

...

class _HomeRouteState extends State<HomeRoute> {

  ...

  Future<void> _initAdMob() {
    // TODO: Initialize AdMob SDK
    return FirebaseAdMob.instance.initialize(appId: AdManager.appId);
  }
}

在此部分中,您将在游戏屏幕顶部添加一个横幅广告,具体如下所示。

580a296a77065928.png 6d6659121dbf382e.png

打开 lib/game_route.dart 文件,并添加以下行以导入 ad_manager.dartfirebase_admob.dart

lib/game_route.dart

...

// TODO: Import ad_manager.dart
import 'package:awesome_drawing_quiz/ad_manager.dart';

// TODO: Import firebase_admob.dart
import 'package:firebase_admob/firebase_admob.dart';

class GameRoute extends StatefulWidget {
  ...
}

接下来,在 _GameRouteState 类中为横幅广告添加以下成员和方法。

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _bannerAd
  BannerAd _bannerAd;

  ...

  // TODO: Implement _loadBannerAd()
  void _loadBannerAd() {
    _bannerAd
      ..load()
      ..show(anchorType: AnchorType.top);
  }

  ...
}

initState() 方法中,创建一个 BannerAd 对象,并加载相应横幅广告。请注意,该横幅广告会显示 320x50 的横幅广告 (AdSize.banner)。

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Initialize _bannerAd
  _bannerAd = BannerAd(
      adUnitId: AdManager.bannerAdUnitId,
      size: AdSize.banner,
  );

  // TODO: Load a Banner Ad
  _loadBannerAd();
}

最后,通过调用 dispose() 回调方法中的 BannerAd.dispose() 方法,释放与 BannerAd 对象关联的资源。

lib/game_route.dart

@override
void dispose() {
  // TODO: Dispose BannerAd object
  _bannerAd?.dispose();

  ...

  super.dispose();
}

大功告成!运行该项目,即可查看横幅广告在游戏屏幕顶部显示的效果。

d82f07411be93d37.png f221e4821191cf99.png

在此部分中,您将在游戏结束后展示一个插页式广告(共 5 个关卡)。

首先,在 _GameRouteState 类中为相应插页式广告添加以下成员和方法。

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _interstitialAd
  InterstitialAd _interstitialAd;

  // TODO: Add _isInterstitialAdReady
  bool _isInterstitialAdReady;

  ...

  // TODO: Implement _loadInterstitialAd()
  void _loadInterstitialAd() {
    _interstitialAd.load();
  }

  // TODO: Implement _onInterstitialAdEvent()
  void _onInterstitialAdEvent(MobileAdEvent event) {
    switch (event) {
      case MobileAdEvent.loaded:
        _isInterstitialAdReady = true;
        break;
      case MobileAdEvent.failedToLoad:
        _isInterstitialAdReady = false;
        print('Failed to load an interstitial ad');
        break;
      case MobileAdEvent.closed:
        _moveToHome();
        break;
      default:
      // do nothing
    }
  }

  ...
}

接下来,在 initState() 方法中初始化 _isInterstitialAdReady_interstitialAd。由于 _onInterstitialAdEvent 已配置为 _interstitialAd 的广告事件监听器,因此所有来自 _interstitialAd 的广告事件都会传递到 _onInterstitialAdEvent 方法。

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Initialize _isInterstitialAdReady
  _isInterstitialAdReady = false;

  // TODO: Initialize _interstitialAd
  _interstitialAd = InterstitialAd(
    adUnitId: AdManager.interstitialAdUnitId,
    listener: _onInterstitialAdEvent,
  );
}

在此 Codelab 中,系统会在用户完成 5 个关卡后展示一个插页式广告。为了尽可能减少不必要的广告请求,我们会在用户完成第 3 个关卡后开始加载广告。

onNewLevel() 方法中,添加以下代码行:

lib/game_route.dart

@override
void onNewLevel(int level, Drawing drawing, String clue) {
  ...

  // TODO: Load an Interstitial Ad
  if (level >= 3 && !_isInterstitialAdReady) {
    _loadInterstitialAd();
  }
}

游戏结束后,系统会显示游戏得分对话框。在用户关闭该对话框后,系统会将用户转到 Awesome Drawing Quizer 的主屏幕。

由于插页式广告应在屏幕切换过程中展示,因此当用户点击 CLOSE 按钮时,系统会显示插页式广告。

按如下方式修改 onGameOver() 方法:

lib/game_route.dart

@override
void onGameOver(int correctAnswers) {
  showDialog(
    context: _scaffoldKey.currentContext,
    builder: (context) {
      return AlertDialog(
        title: Text('Game over!'),
        content: Text('Score: $correctAnswers/5'),
        actions: <Widget>[
          FlatButton(
            child: Text('close'.toUpperCase()),
            onPressed: () {

              // TODO: Display an Interstitial Ad
              if (_isInterstitialAdReady) {
                _interstitialAd.show();
              }

              _moveToHome();
            },
          ),
        ],
      );
    },
  );
}

最后,通过调用 dispose() 回调方法中的 InterstitialAd.dispose() 方法,释放与 InterstitialAd 对象关联的资源。

lib/game_route.dart

@override
void dispose() {
  ...

  // TODO: Dispose InterstitialAd object
  _interstitialAd?.dispose();

  ...

  super.dispose();
}

大功告成!运行该项目,即可查看插页式广告在游戏结束后显示的效果。

53f44b98e8a0c446.gif

在此部分中,您将添加激励广告,以便为用户提供额外提示作为奖励。

首先,在 _GameRouteState 类中为激励广告添加相应成员和方法。请注意,RewardedVideoAd 是单例对象,因此您无需添加用于管理 RewardedVideoAd 类实例的成员。

RewardedVideoAdEvent.rewarded 是激励广告中最重要的广告事件。该事件会在用户符合获得奖励的条件(例如,看完某个视频)时触发。在此 Codelab 中,RewardedVideoAdEvent.rewarded 会调用 QuizManager.instance.useHint() 方法,该方法会在提示字符串中再显示一个字符。

此外,RewardedVideoAdEvent.rewarded 会根据该广告事件来更改 _isRewardedAdReady 的值,以便更新界面。请注意,_isRewardedAdReady 会在用户关闭广告时重新加载广告,以确保广告尽早准备就绪。

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _isRewardedAdReady
  bool _isRewardedAdReady;

  ...

  // TODO: Implement _loadRewardedAd()
  void _loadRewardedAd() {
    RewardedVideoAd.instance.load(
      targetingInfo: MobileAdTargetingInfo(),
      adUnitId: AdManager.rewardedAdUnitId,
    );
  }

  // TODO: Implement _onRewardedAdEvent()
  void _onRewardedAdEvent(RewardedVideoAdEvent event,
      {String rewardType, int rewardAmount}) {
    switch (event) {
      case RewardedVideoAdEvent.loaded:
        setState(() {
          _isRewardedAdReady = true;
        });
        break;
      case RewardedVideoAdEvent.closed:
        setState(() {
          _isRewardedAdReady = false;
        });
        _loadRewardedAd();
        break;
      case RewardedVideoAdEvent.failedToLoad:
        setState(() {
          _isRewardedAdReady = false;
        });
        print('Failed to load a rewarded ad');
        break;
      case RewardedVideoAdEvent.rewarded:
        QuizManager.instance.useHint();
        break;
      default:
      // do nothing
    }
  }

  ...
}

接下来,初始化 _isRewardedAdReady 并将 _onRewardedAdEvent 设为广告事件监听器。然后,调用 _loadRewardedAd() 以请求激励广告。

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Initialize _isRewardedAdReady
  _isRewardedAdReady = false;

  // TODO: Set Rewarded Ad event listener
  RewardedVideoAd.instance.listener = _onRewardedAdEvent;

  // TODO: Load a Rewarded Ad
  _loadRewardedAd();
}

接下来,让用户能够点击悬浮操作按钮,以便观看激励广告。只有在用户在当前关卡中未使用提示,并且激励广告已加载的情况下,该按钮才会显示。

按以下方式修改 _buildFloatingActionButton() 方法,以便显示悬浮操作按钮。请注意,如果返回 null,则会在屏幕中隐藏该按钮。

lib/game_route.dart

Widget _buildFloatingActionButton() {
  // TODO: Return a FloatingActionButton if a Rewarded Ad is available
  return (!QuizManager.instance.isHintUsed && _isRewardedAdReady)
      ? FloatingActionButton.extended(
          onPressed: () {
            showDialog(
              context: context,
              builder: (context) {
                return AlertDialog(
                  title: Text('Need a hint?'),
                  content: Text('Watch an Ad to get a hint!'),
                  actions: <Widget>[
                    FlatButton(
                      child: Text('cancel'.toUpperCase()),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                    FlatButton(
                      child: Text('ok'.toUpperCase()),
                      onPressed: () {
                        Navigator.pop(context);
                        RewardedVideoAd.instance.show();
                      },
                    ),
                  ],
                );
              },
            );
          },
          label: Text('Hint'),
          icon: Icon(Icons.card_giftcard),
        )
      : null;
}

最后,在 dispose() 回调方法中移除激励广告事件监听器。

lib/game_route.dart

@override
void dispose() {
  ...

  // TODO: Remove Rewarded Ad event listener
  RewardedVideoAd.instance.listener = null;

  ...

  super.dispose();
}

大功告成!运行该项目并观看激励广告,即可获取更多提示。

2a79a3db6b44dae9.gif

9db81af632cb2b15.png您发现了一些特别内容!

您已完成此 Codelab 的相关学习。您可以在 android_studio_folder.pngcomplete 文件夹中找到此 Codelab 的完整代码。

如需了解详情,请尝试学习其他 Flutter Codelab