許多開發者使用廣告來透過他們的移動應用和遊戲獲利。這使得他們的應用可以免費下載,從而提高了應用的普及度。

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. key 標籤包圍 GADApplicationIdentifier

  3. string 標籤包圍您的 AdMob 應用 ID。您在步驟 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
/// 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.
          ? const 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”。您可以在 廣告單元 部分找到這些 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.
            ? const 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();
  }

}