【2021年永久保存版】Flutter2.xでGoogle Mobile Adsを使う

スポンサーリンク
アプリ開発

flutterアプリにおいて広告の表示方法を備忘がてらにまとめておきます。

どのようにFlutterを学んでいる?

私は書籍でFlutterを学んでいます。おすすめは基礎から学ぶ Flutterです。

基礎から学ぶFlutter

プログラミングの基礎の内容やさまざまなウィジェットの使い方などググっても見つけることが難しいような情報が詰まっています。

Google Mobile Ads SDK for Flutterのサポート範囲

Google Mobile Ads SDK for Flutterは以下のような内容をサポートしています。

  • バナー広告の表示
  • インタースティシャル広告の表示
  • ネイティブ広告の表示
  • リワード付き動画広告の読み込みと表示

Mobile Ads SDKをインポートする

pubspec.yamlにgoogle_mobile_adsを追加する

pubspec.yamlファイルに以下のように記載します。

dependencies:
  flutter:
    sdk: flutter
    
  google_mobile_ads: ^0.11.0+2

flutter pub get でインストールする

flutter pub get

importする

広告表示をしたいファイルで以下の一行を追加します。

import 'package:google_mobile_ads/google_mobile_ads.dart';

プラットホームごとの設定(iOS/Android)

iOS用に設定する

Info.plistを更新する

以下のように、AdMobアプリIDをGADApplicationIdentifierキーに追加する。

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

Android用に設定する

AndroidManifest.xmlを更新する

AdMobアプリIDがAndroidManifest.xmlに含まれていなければアプリ起動時にクラッシュします。

以下のようにAdMobアプリIDを更新します。

<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>

Mobile Ads SDKの初期化

ここまでで準備は完了です。

次は実際に広告を表示させる前に初期化処理を実装しておきます。

MobileAds.instance.initialize()を呼び出す

広告を読み込む前に、MobileAds.instance.initialize()を呼び出してアプリにMobile Ads SDKを初期化させ流必要があります。理想的にはアプリを実行する直前に実行する必要があります。

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

void main() {
  //以下の二行を追加
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();
  //追加ここまで

  runApp(MyApp());
}

広告を表示する

上述しましたが、以下のような広告を表示させることが出来ます。

  • バナー広告の表示
  • インタースティシャル広告の表示
  • ネイティブ広告の表示
  • リワード付き動画広告の読み込みと表示

バナー広告を表示する

バナー広告はアプリの上部か下部のどちらかに表示させることができます。ユーザーがアプリを操作している間は画面に表示され続け、一定時間後に自動的に更新されます。

テストの際は常にテスト広告を利用すること

広告の表示テストをするときには、本番広告ではなく、テスト広告を使用してください。 アカウントが停止される可能性があります。テスト広告用の広告ユニットIDがあるのでそれを使いましょう。

Android(バナー):ca-app-pub-3940256099942544/6300978111

iOS(バナー):ca-app-pub-3940256099942544/2934735716

当たり前ですが、アプリを公開する際にはこれを必ず本番用に置き換えましょう。

バナー広告を初期化する

前置きが長くなってしまいましたが、バナー広告を表示させてみましょう。

//プラットホームごとのテスト広告IDを取得するメソッドをどこかに配置してください。
String getTestAdBannerUnitId(){
  String testBannerUnitId = "";
  if(Platform.isAndroid) {
    // Android のとき
    testBannerUnitId = "ca-app-pub-3940256099942544/6300978111";
  } else if(Platform.isIOS) {
    // iOSのとき
    testBannerUnitId = "ca-app-pub-3940256099942544/2934735716";
  }
  return testBannerUnitId;
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  final BannerAd myBanner = BannerAd(
    adUnitId: getTestAdBannerUnitId(),
    size: AdSize.banner,
    request: AdRequest(),
    listener: AdListener(),
  );
  //.......

  //.......
}

バナー広告を読み込む

BannerAdがインスタンス化された後、画面に表示する前にload()を呼び出す必要があります。

@override
Widget build(BuildContext context) {
  myBanner.load();
  //........
}

バナー広告を表示する

BannerAdをウィジェットとして表示するには、load()を呼び出した後、AdWidgetをインスタンス化します。

@override
Widget build(BuildContext context) {
  myBanner.load();
  final AdWidget adWidget = AdWidget(ad: myBanner);
  //.......
}

AdWidgetはFlutterのWidgetクラスを継承しているため、他のウィジェットと同じように使用できます。 iOSでは、ウィジェットを指定された幅と高さのウィジェットに配置してください。 そうしないと、広告が表示されない場合があります。 BannerAdは、広告と一致するサイズのコンテナに配置できます。

@override
Widget build(BuildContext context) {
  myBanner.load();
  
  final AdWidget adWidget = AdWidget(ad: myBanner);
  
  final Container adContainer = Container(
    alignment: Alignment.center,
    child: adWidget,
    width: myBanner.size.width.toDouble(),
    height: myBanner.size.height.toDouble(),
  );
  //......
}

以下のように作成したContainerを表示させてみましょう。

children: <Widget>[
  adContainer,
],

表示された画面のキャプチャ

表示された画面

バナー広告表示時にエラーが出る?

次のようなエラーが出ることがあります。そんな時は、build.gradleを以下のように書き換えます。

uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:google_mobile_ads] /Users/uedive/AndroidStudioProjects/quiz_share/build/google_mobile_ads/intermediates/library_manifest/debug/AndroidManifest.xml as the library might be using APIs not available in 16
Suggestion: use a compatible library with a minSdk of at most 16,
or increase this project's minSdk version to at least 19,
or use tools:overrideLibrary="io.flutter.plugins.googlemobileads" to force usage (may lead to runtime failures)
defaultConfig {
    // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
    applicationId "XXX.XXXXX.XXX"
    minSdkVersion 19
    targetSdkVersion 30
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
}

広告がload()を呼び出すと、アクセスが不要になったときにdispose()を呼び出す必要があります。 dispose()を呼び出すときのベストプラクティスは、AdWidgetがウィジェットツリーから削除された後、またはAdListener.onAdFailedToLoadコールバック内のいずれかです。

バナーサイズについて

上記のコードにてsize: AdSize.bannerとありますが、バナー広告のサイズを変更することも可能です。

サイズ(dp)サイズの説明AdSize定数
320×50標準的なバナーbanner
320×100大きめのバナーlargeBanner
320×250中程度の長方形mediumRectangle
468×60フルサイズバナーfullBanner
728×90リーダーボードleaderboard
表:バナー広告のサイズ一覧

任意のサイズのバナーを表示したい場合は以下のように指定することも可能です。

final AdSize adSize = AdSize(300, 50);

バナー広告のイベントについて

AdListenerを利用すると、広告が閉じられたときやユーザーがアプリを閉じたときなどのイベントをリッスンすることができます。

この際はバナー広告の初期化の際に以下のコードを利用してください。

final BannerAd myBanner = BannerAd(
  adUnitId: getTestAdBannerUnitId(),
  size: AdSize.banner,
  request: AdRequest(),
  listener: AdListener(
    // 広告が正常にロードされたときに呼ばれます。
    onAdLoaded: (Ad ad) => print('バナー広告がロードされました。'),
    // 広告のロードが失敗した際に呼ばれます。
    onAdFailedToLoad: (Ad ad, LoadAdError error) {
      print('バナー広告のロードに失敗しました。: $error');
    },
    // 広告が開かれたときに呼ばれます。
    onAdOpened: (Ad ad) => print('バナー広告が開かれました。'),
    // 広告が閉じられたときに呼ばれます。
    onAdClosed: (Ad ad) => print('バナー広告が閉じられました。'),
    // ユーザーがアプリを閉じるときに呼ばれます。
    onApplicationExit: (Ad ad) => print('ユーザーがアプリを離れました。'),
  ),
);

インタースティシャル(Interstitial)広告を表示する

インタースティシャル広告はフルスクリーンの広告です。ユーザーは広告をタップするか閉じるボタンを押すか選択できます。

テストの際は常にテスト広告を利用すること

広告の表示テストをするときには、本番広告ではなく、テスト広告を使用してください。 アカウントが停止される可能性があります。テスト広告用の広告ユニットIDがあるのでそれを使いましょう。

Android(インタースティシャル):ca-app-pub-3940256099942544/1033173712

iOS(インタースティシャル):ca-app-pub-3940256099942544/4411468910

当たり前ですが、アプリを公開する際にはこれを必ず本番用に置き換えましょう。

インタースティシャル広告を初期化する

//プラットホームごとのテスト広告IDを取得するメソッドをどこかに配置してください。
String getTestAdInterstitialUnitId(){
  String testBannerUnitId = "";
  if(Platform.isAndroid) {
    // Android のとき
    testBannerUnitId = "ca-app-pub-3940256099942544/1033173712";
  } else if(Platform.isIOS) {
    // iOSのとき
    testBannerUnitId = "ca-app-pub-3940256099942544/4411468910";
  }
  return testBannerUnitId;
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  final InterstitialAd myInterstitial = InterstitialAd(
    adUnitId: getTestAdInterstitialUnitId(),
    request: AdRequest(),
    listener: AdListener(),
  );
  //.......

  //.......
}

インタースティシャル広告を読み込む

InterstitialAdがインスタンス化された後、画面に表示する前にload()を呼び出す必要があります。

@override
Widget build(BuildContext context) {
  myInterstitial.load();
  //........
}

インタースティシャル広告を表示する

インタースティシャル広告はアプリの全面に静的に配置されるため、Flutterウィジェットツリーに追加することはできません。

そのため、広告が読み込まれた後にshow()を呼び出すことでインタースティシャル広告を表示させます。

今回はデフォルトで作成されている_incrementCounter()show()を呼び出すことでカウンターがプラスされたときに広告を表示させるようにしてみました。

@override
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.

      // ここに追加しました!!
      myInterstitial.show();
      // ここに追加しました!!
      _counter++;
    });
  }
  //..........

}

インタースティシャル広告のイベントについて

AdListenerを利用すると、広告が閉じられたときやユーザーがアプリを閉じたときなどのイベントをリッスンすることができます。

「インタースティシャル広告を閉じられたときに画面遷移する」などの処理の実装はここで実施しましょう。

この場合、インタースティシャル広告の初期化の際に以下のコードを使いましょう。

final InterstitialAd myInterstitial = InterstitialAd(
  adUnitId: getTestAdInterstitialUnitId(),
  request: AdRequest(),
  listener: AdListener(
    // 広告が正常にロードされたときに呼ばれます。
    onAdLoaded: (Ad ad) => print('インタースティシャル広告がロードされました。'),
    // 広告のロードが失敗した際に呼ばれます。
    onAdFailedToLoad: (Ad ad, LoadAdError error) {
      print('インタースティシャル広告のロードに失敗しました。: $error');
    },
    // 広告が開かれたときに呼ばれます。
    onAdOpened: (Ad ad) => print('インタースティシャル広告が開かれました。'),
    // 広告が閉じられたときに呼ばれます。
    onAdClosed: (Ad ad) => print('インタースティシャル広告が閉じられました。'),
    // ユーザーがアプリを閉じるときに呼ばれます。
    onApplicationExit: (Ad ad) => print('ユーザーがアプリを離れました。'),
  ),
);

報酬付き(リワード)広告(Rewarded Ads)を表示する

報酬付き広告(リワード広告)はユーザーがアプリ内で取得できる報酬と引き換えに表示する広告です。

テストの際は常にテスト広告を利用すること

広告の表示テストをするときには、本番広告ではなく、テスト広告を使用してください。 アカウントが停止される可能性があります。テスト広告用の広告ユニットIDがあるのでそれを使いましょう。

Android(インタースティシャル):ca-app-pub-3940256099942544/5224354917

iOS(インタースティシャル):ca-app-pub-3940256099942544/1712485313

当たり前ですが、アプリを公開する際にはこれを必ず本番用に置き換えましょう。

リワード広告を初期化する

ロードしたRewardedAdで複数回show()を呼び出さないようにする必要があります。

そのため、AdListener.onAdFailedToLoad()AdListener.onAdClosed()dispose()を読んでおきましょう。

また、報酬を獲得した後もdispose()されるようにイベントに追加しておきましょう。

広告のイベントも込みの初期化コードを以下に示しておきます。

//プラットホームごとのテスト広告IDを取得するメソッドをどこかに配置してください。
String getTestAdRewardedUnitId(){
  String testBannerUnitId = "";
  if(Platform.isAndroid) {
    // Android のとき
    testBannerUnitId = "ca-app-pub-3940256099942544/5224354917";
  } else if(Platform.isIOS) {
    // iOSのとき
    testBannerUnitId = "ca-app-pub-3940256099942544/1712485313";
  }
  return testBannerUnitId;
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  final RewardedAd myRewarded = RewardedAd(
    adUnitId: getTestAdRewardedUnitId(),
    request: AdRequest(),
    listener: AdListener(
      // Called when an ad is successfully received.
      onAdLoaded: (Ad ad) => print('リワード広告を読み込みました。'),
      // Called when an ad request failed.
      onAdFailedToLoad: (Ad ad, LoadAdError error) {
        ad.dispose();
        print('リワード広告の読み込みに失敗しました。: $error');
      },
      // Called when an ad opens an overlay that covers the screen.
      onAdOpened: (Ad ad) => print('リワード広告が開かれました。'),
      // Called when an ad removes an overlay that covers the screen.
      onAdClosed: (Ad ad) => print('リワード広告が閉じられました。'),
      // Called when an ad is in the process of leaving the application.
      onApplicationExit: (Ad ad) => print('ユーザーがアプリを離れました。'),
      // Called when a RewardedAd triggers a reward.
      onRewardedAdUserEarnedReward: (RewardedAd ad, RewardItem reward) {
        ad.dispose();
        print('報酬を獲得しました!: $reward');
      },
    ),
  );
  //.......

  //.......
}

リワード広告を読み込む

RewardedAdがインスタンス化された後、画面に表示する前にload()を呼び出す必要があります。

@override
Widget build(BuildContext context) {
  myRewarded.load();
  //........
}

リワード広告を表示する

リワード広告はアプリの全面に静的に配置されるため、Flutterウィジェットツリーに追加することはできません。

そのため、広告が読み込まれた後にshow()を呼び出すことでリワード広告を表示させます。

今回はデフォルトで作成されている_incrementCounter()でshow()を呼び出すことでカウンターがプラスされたときに広告を表示させるようにしてみました。

@override
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.

      // ここに追加しました!!
      myRewarded.show();
      // ここに追加しました!!
      _counter++;
    });
  }
  //..........

}

リワード広告の実行結果

リワード広告の表示例
リワード広告の表示例
I/flutter (16030): 報酬を獲得しました!: Instance of 'RewardItem'

コメント

タイトルとURLをコピーしました