Skip to main content

在你的 Flutter 移动应用或游戏中添加广告

许多开发者使用广告来盈利他们的移动应用和游戏。这使得他们的应用可以免费下载,从而提升应用的流行度。

智能手机显示广告的插图

要在你的 Flutter 项目中添加广告,请使用 Google 的移动广告平台 AdMob。本食谱演示了如何使用 google_mobile_ads 包向你的应用或游戏中添加横幅广告。

1. 获取 AdMob 应用 ID

#
  1. 前往 AdMob 并设置一个帐户。这可能需要一些时间,因为你需要提供银行信息、签署合同等等。

  2. AdMob 帐户准备就绪后,在 AdMob 中创建两个 应用:一个用于 Android,一个用于 iOS。

  3. 打开 应用设置 部分。

  4. 获取 Android 应用和 iOS 应用的 AdMob 应用 ID。它们类似于 ca-app-pub-1234567890123456~1234567890。注意两个数字之间的波浪号 (~)。

    AdMob 屏幕截图,显示应用 ID 的位置

2. 平台特定设置

#

更新你的 Android 和 iOS 配置以包含你的应用 ID。

Android

#

将你的 AdMob 应用 ID 添加到你的 Android 应用中。

  1. 打开应用的 android/app/src/main/AndroidManifest.xml 文件。

  2. 添加一个新的 <meta-data> 标签。

  3. 使用 com.google.android.gms.ads.APPLICATION_ID 的值设置 android:name 元素。

  4. 使用你在上一步中获得的自己的 AdMob 应用 ID 设置 android:value 元素。将其包含在引号中,如下所示:

    xml
    <manifest>
        <application>
            ...
    
            <!-- 示例 AdMob 应用 ID:ca-app-pub-3940256099942544~3347511713 -->
            <meta-data
                android:name="com.google.android.gms.ads.APPLICATION_ID"
                android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
        </application>
    </manifest>

iOS

#

将你的 AdMob 应用 ID 添加到你的 iOS 应用中。

  1. 打开你的应用的 ios/Runner/Info.plist 文件。

  2. 将 GADApplicationIdentifier 用 key 标签括起来。

  3. 将你的 AdMob 应用 ID 用 string 标签括起来。你在 步骤 1 中创建了这个 AdMob 应用 ID。

    xml
    <key>GADApplicationIdentifier</key>
    <string>ca-app-pub-################~##########</string>

3. 添加 google_mobile_ads 插件

#

要添加 google_mobile_ads 插件作为依赖项,请运行 flutter pub add:

flutter pub add google_mobile_ads

4. 初始化移动广告 SDK

#

在加载广告之前,你需要初始化移动广告 SDK。

  1. 调用 MobileAds.instance.initialize() 来初始化移动广告 SDK。

    dart
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      unawaited(MobileAds.instance.initialize());
    
      runApp(const MyApp());
    }

如上所示,在启动时运行初始化步骤,以便 AdMob SDK 有足够的时间在需要之前初始化。

5. 加载横幅广告

#

要显示广告,你需要从 AdMob 请求广告。

要加载横幅广告,请构造一个 BannerAd 实例,并对其调用 load()。

dart
/// 加载横幅广告。
void _loadAd() {
  final bannerAd = BannerAd(
    size: widget.adSize,
    adUnitId: widget.adUnitId,
    request: const AdRequest(),
    listener: BannerAdListener(
      // 成功接收广告时调用。
      onAdLoaded: (ad) {
        if (!mounted) {
          ad.dispose();
          return;
        }
        setState(() {
          _bannerAd = ad as BannerAd;
        });
      },
      // 广告请求失败时调用。
      onAdFailedToLoad: (ad, error) {
        debugPrint('BannerAd failed to load: $error');
        ad.dispose();
      },
    ),
  );

  // 开始加载。
  bannerAd.load();
}

要查看完整的示例,请查看本食谱的最后一步。

6. 显示横幅广告

#

获得加载后的 BannerAd 实例后,使用 AdWidget 来显示它。

dart
AdWidget(ad: _bannerAd)

最好将小部件包装在 SafeArea 中(这样设备凹口就不会遮挡广告的任何部分)和 SizedBox 中(这样它在加载之前和之后都具有指定的常量大小)。

dart
@override
Widget build(BuildContext context) {
  return SafeArea(
    child: SizedBox(
      width: widget.adSize.width.toDouble(),
      height: widget.adSize.height.toDouble(),
      child: _bannerAd == null
          // 尚未渲染任何内容。
          ? const SizedBox()
          // 实际广告。
          : AdWidget(ad: _bannerAd!),
    ),
  );
}

不再需要访问广告时,必须将其释放。调用 dispose() 的最佳实践是在 AdWidget 从窗口小部件树中移除之后或在 BannerAdListener.onAdFailedToLoad() 回调中。

dart
_bannerAd?.dispose();

7. 配置广告

#

要显示测试广告以外的任何内容,你必须注册广告单元。

  1. 打开 AdMob。

  2. 为每个 AdMob 应用创建一个 广告单元。

    AdMob 网页 UI 中广告单元位置的屏幕截图

    这会询问广告单元的格式。AdMob 提供了横幅广告以外的许多格式——插页式广告、奖励广告、应用打开广告等等。这些广告的 API 类似,并在 AdMob 文档 和 官方示例 中有介绍。

  3. 选择横幅广告。

  4. 获取 Android 应用和 iOS 应用的 广告单元 ID。你可以在 广告单元 部分找到这些 ID。它们看起来像 ca-app-pub-1234567890123456/1234567890。格式类似于 应用 ID,但两个数字之间有一个斜杠 (/)。这将 广告单元 ID 与 应用 ID 区分开来。

    AdMob 网页 UI 中广告单元 ID 的屏幕截图

  5. 根据目标应用平台,将这些 广告单元 ID 添加到 BannerAd 的构造函数中。

    dart
    final String adUnitId = Platform.isAndroid
        // 在 Android 上使用此广告单元...
        ? 'ca-app-pub-3940256099942544/6300978111'
        // ...或在 iOS 上使用此广告单元。
        : 'ca-app-pub-3940256099942544/2934735716';

8. 收尾工作

#

要在已发布的应用或游戏中显示广告(而不是调试或测试场景),你的应用必须满足其他要求:

  1. 你的应用必须经过审核和批准才能完全投放广告。 请遵循 AdMob 的 应用准备就绪指南。例如,你的应用必须至少列在一个受支持的商店中,例如 Google Play 商店或 Apple App Store。

  2. 你必须 创建 app-ads.txt 文件 并将其发布在你的开发者网站上。

智能手机显示广告的插图

要了解有关应用和游戏盈利的更多信息,请访问 AdMob 和 Ad Manager 的官方网站。

9. 完整示例

#

以下代码实现了一个简单的有状态窗口小部件,它加载横幅广告并显示它。

dart
import 'dart:io';

import 'package:flutter/widgets.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

class MyBannerAdWidget extends StatefulWidget {
  /// 请求的横幅大小。默认为 [AdSize.banner]。
  final AdSize adSize;

  /// 要显示的 AdMob 广告单元。
  ///
  /// TODO:用你自己的广告单元替换这个测试广告单元
  final String adUnitId = Platform.isAndroid
      // 在 Android 上使用此广告单元...
      ? 'ca-app-pub-3940256099942544/6300978111'
      // ...或在 iOS 上使用此广告单元。
      : 'ca-app-pub-3940256099942544/2934735716';

  MyBannerAdWidget({
    super.key,
    this.adSize = AdSize.banner,
  });

  @override
  State<MyBannerAdWidget> createState() => _MyBannerAdWidgetState();
}

class _MyBannerAdWidgetState extends State<MyBannerAdWidget> {
  /// 要显示的横幅广告。在广告实际加载之前,它是 `null`。
  BannerAd? _bannerAd;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: SizedBox(
        width: widget.adSize.width.toDouble(),
        height: widget.adSize.height.toDouble(),
        child: _bannerAd == null
            // 尚未渲染任何内容。
            ? const SizedBox()
            // 实际广告。
            : AdWidget(ad: _bannerAd!),
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    _loadAd();
  }

  @override
  void dispose() {
    _bannerAd?.dispose();
    super.dispose();
  }

  /// 加载横幅广告。
  void _loadAd() {
    final bannerAd = BannerAd(
      size: widget.adSize,
      adUnitId: widget.adUnitId,
      request: const AdRequest(),
      listener: BannerAdListener(
        // 成功接收广告时调用。
        onAdLoaded: (ad) {
          if (!mounted) {
            ad.dispose();
            return;
          }
          setState(() {
            _bannerAd = ad as BannerAd;
          });
        },
        // 广告请求失败时调用。
        onAdFailedToLoad: (ad, error) {
          debugPrint('BannerAd failed to load: $error');
          ad.dispose();
        },
      ),
    );

    // 开始加载。
    bannerAd.load();
  }
}