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. GADApplicationIdentifierkey 标签括起来。

  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 文件 并将其发布在你的开发者网站上。

智能手机显示广告的插图

要了解有关应用和游戏盈利的更多信息,请访问 AdMobAd 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();
  }
}