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

许多开发者使用广告来为他们的移动应用程序和游戏盈利。这使得他们的应用程序可以免费下载,从而提高了应用程序的普及度。

An illustration of a smartphone showing an ad

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

1. 获取 AdMob 应用 ID

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

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

  3. 打开应用程序设置部分。

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

    Screenshot from AdMob showing the location of the App ID

2. 平台特定设置

#

更新您的 Android 和 iOS 配置以包含您的应用程序 ID。

Android

#

将您的 AdMob 应用程序 ID 添加到您的 Android 应用程序。

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

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

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

  4. android:value 元素的值设置为您在上一步骤中获得的自己的 AdMob 应用程序 ID。将它们包含在引号中,如所示

    xml
    <manifest>
        <application>
            ...
    
            <!-- Sample AdMob app 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

#

您需要在加载广告之前初始化 Mobile Ads SDK。

  1. 调用MobileAds.instance.initialize() 初始化 Mobile Ads SDK。

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

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

5. 加载横幅广告

#

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

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

dart
/// Loads a banner ad.
void _loadAd() {
  final bannerAd = BannerAd(
    size: widget.adSize,
    adUnitId: widget.adUnitId,
    request: const AdRequest(),
    listener: BannerAdListener(
      // Called when an ad is successfully received.
      onAdLoaded: (ad) {
        if (!mounted) {
          ad.dispose();
          return;
        }
        setState(() {
          _bannerAd = ad as BannerAd;
        });
      },
      // Called when an ad request failed.
      onAdFailedToLoad: (ad, error) {
        debugPrint('BannerAd failed to load: $error');
        ad.dispose();
      },
    ),
  );

  // Start loading.
  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
          // Nothing to render yet.
          ? SizedBox()
          // The actual ad.
          : AdWidget(ad: _bannerAd!),
    ),
  );
}

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

dart
_bannerAd?.dispose();

7. 配置广告

#

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

  1. 打开AdMob

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

    Screenshot of the location of Ad Units in AdMob web UI

    这会询问广告单元的格式。AdMob 提供了多种格式,除了横幅广告之外,还有插页式广告、奖励广告、应用打开广告等等。这些格式的 API 类似,并在AdMob 文档官方示例中进行了说明。

  3. 选择横幅广告。

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

    Screenshot of an Ad Unit ID in AdMob web UI

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

    dart
    final String adUnitId = Platform.isAndroid
        // Use this ad unit on Android...
        ? 'ca-app-pub-3940256099942544/6300978111'
        // ... or this one on iOS.
        : 'ca-app-pub-3940256099942544/2934735716';

8. 最后润色

#

要在一个已发布的应用或游戏中显示广告(与调试或测试场景相反),您的应用必须满足其他要求。

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

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

An illustration of a smartphone showing an ad

要了解有关应用和游戏获利的更多信息,请访问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 {
  /// The requested size of the banner. Defaults to [AdSize.banner].
  final AdSize adSize;

  /// The AdMob ad unit to show.
  ///
  /// TODO: replace this test ad unit with your own ad unit
  final String adUnitId = Platform.isAndroid
      // Use this ad unit on Android...
      ? 'ca-app-pub-3940256099942544/6300978111'
      // ... or this one on iOS.
      : 'ca-app-pub-3940256099942544/2934735716';

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

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

class _MyBannerAdWidgetState extends State<MyBannerAdWidget> {
  /// The banner ad to show. This is `null` until the ad is actually loaded.
  BannerAd? _bannerAd;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: SizedBox(
        width: widget.adSize.width.toDouble(),
        height: widget.adSize.height.toDouble(),
        child: _bannerAd == null
            // Nothing to render yet.
            ? SizedBox()
            // The actual ad.
            : AdWidget(ad: _bannerAd!),
      ),
    );
  }

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

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

  /// Loads a banner ad.
  void _loadAd() {
    final bannerAd = BannerAd(
      size: widget.adSize,
      adUnitId: widget.adUnitId,
      request: const AdRequest(),
      listener: BannerAdListener(
        // Called when an ad is successfully received.
        onAdLoaded: (ad) {
          if (!mounted) {
            ad.dispose();
            return;
          }
          setState(() {
            _bannerAd = ad as BannerAd;
          });
        },
        // Called when an ad request failed.
        onAdFailedToLoad: (ad, error) {
          debugPrint('BannerAd failed to load: $error');
          ad.dispose();
        },
      ),
    );

    // Start loading.
    bannerAd.load();
  }
}