FlutterでAdMob広告の実装（アプリ起動、リワード、インターステイシャル）

結論から言うと今回の僕が伝える内容は下記です。

    アプリ起動広告
    インタースティシャル広告
    リワード広告
    リワードインタースティシャル広告

手っ取り早くソースくれって方はこちらをどうぞ

https://github.com/aki19930119/admobSample

##### ①広告表示の知識がほぼない人や簡単に表示するための流れが知りたいと言う方はこちらをみて進めた方が早いと思います。

https://yaba-blog.com/flutter-admob/

##### ②ただ上記のやつでは表示はできなかったので、下記を僕は利用してバナー表示をさせました。

https://techgamelife.net/2022/01/14/flutter-admob-banner/


話は流れましたが上記を踏まえてある程度表示とかできたけど、表示したいのはアプリ広告とかリワード広告とかなんだよな。
なんて方はこちらの記事は参考になるかなと思います。

全て反映したものはmain.dartです。
importでエラーが出ると思いますが、こんな感じでディレクトリ置いてあるよとかわかると思うのでそちらも添付します。

<img width="300" alt="スクリーンショット 2023-04-17 19.09.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/a0d4d24f-a76b-0e15-97b0-c9c956fec6a1.png">

AdBannerとadmob.dartのところは無視してくださいませ。

前置きは少し長くなりましたが、Managerクラスはコピペで行けるしmainクラスもコピペでimportを変更するくらいなので少しは考える必要ありますが、①②の流れをある程度理解できた方はそこまで難しくないと思います。

参考程度にどうぞ。（全てテスト広告の内容なので表示できます。）

pubspeck.yaml

      google_mobile_ads: ^1.0.0


info.plist

    <key>GADApplicationIdentifier</key>
    <string>ca-app-pub-3940256099942544~1458002511</string>

AndroidManifest.xml

       <meta-data
           android:name="com.google.android.gms.ads.APPLICATION_ID"
           android:value="ca-app-pub-3940256099942544~3347511713"/>


build.gradleにもなんか設定必要ですが、上記で紹介した記事見ながらググったりしてください。

## main.dart

    import 'package:admob/Manager/AppOpenAdManager.dart';
    import 'package:admob/Manager/RewardedAdManager.dart';
    import 'package:flutter/material.dart';
    import 'package:google_mobile_ads/google_mobile_ads.dart';
    
    import 'AdBanner.dart';
    import 'Manager/InterstitialAdManager.dart';
    import 'Manager/RewardedInterstitialAdManager.dart';
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      MobileAds.instance.initialize();
    
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key, required this.title});
        
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
    
      AppOpenAdManager appOpenAdManager = AppOpenAdManager();
      RewardedAdManager rewardedAdManager = RewardedAdManager();
      InterstitialAdManager interstitialAdManager = InterstitialAdManager();
      RewardedInterstitialAdManager rewardedInterstitialAdManager = RewardedInterstitialAdManager();
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        rewardedAdManager.loadRewardedAd();
        rewardedInterstitialAdManager.loadAd();
        interstitialAdManager.interstitialAd();
        appOpenAdManager.loadAd();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                ElevatedButton(
                  child: Text('Show Interstitial Ad'),
                  onPressed: interstitialAdManager.showInterstitialAd,
                  // onPressed: showAd,
    
                ),
                ElevatedButton(
                  child: Text('Show Rewarded Ad'),
                  onPressed: rewardedAdManager.showRewardedAd,
                  // onPressed: showAd,
    
                ),
    
                ElevatedButton(
                  child: Text('Show RewardedInterstitial Ad'),
                  onPressed: rewardedInterstitialAdManager.showAd,
                  // onPressed: showAd,
    
                ),
    
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headlineMedium,
                ),
                Spacer(),

                const Text(
                  'You have pushed the button this many times:',
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: const Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }

## アプリ起動

    import 'dart:io';
    import 'package:google_mobile_ads/google_mobile_ads.dart';
    
    class AppOpenAdManager implements AppOpenAdLoadCallback {
      AppOpenAd? _appOpenAd;
      bool _isAdLoaded = false;
    
      void loadAd() {
        AppOpenAd.load(
          adUnitId: Platform.isAndroid
              ? 'ca-app-pub-3940256099942544/3419835294'
              : "ca-app-pub-3940256099942544/5662855259",
          request: AdRequest(),
          orientation: AppOpenAd.orientationPortrait,
          adLoadCallback: AppOpenAdLoadCallback(
            onAdLoaded: (ad) {
              _appOpenAd = ad;
              _isAdLoaded = true;
              _appOpenAd?.show();
            },
            onAdFailedToLoad: (error) {
              print('App open ad failed to load: $error');
            },
          ),
        );
      }
    
      void showAdIfLoaded() {
        if (_isAdLoaded) {
          _appOpenAd?.show();
        } else {
          loadAd();
        }
      }
    
      void onAppOpenAdLoaded(AppOpenAd ad) {
        _appOpenAd = ad;
        _isAdLoaded = true;
        showAdIfLoaded();
      }
    
      void onAppOpenAdFailedToLoad(LoadAdError error) {
        print('App open ad failed to load: $error');
      }
    
      @override
      void onAppOpenAdClosed() {
        _appOpenAd?.dispose();
        _isAdLoaded = false;
        loadAd();
      }
    
      void dispose() {
        _appOpenAd?.dispose();
      }
    
      @override
      // TODO: implement onAdFailedToLoad
      FullScreenAdLoadErrorCallback get onAdFailedToLoad => throw UnimplementedError();
    
      @override
      // TODO: implement onAdLoaded
      GenericAdEventCallback<AppOpenAd> get onAdLoaded => throw UnimplementedError();
    }

## インタースティシャル

    import 'package:google_mobile_ads/google_mobile_ads.dart';
    import 'dart:io';
    
    class InterstitialAdManager implements InterstitialAdLoadCallback{
      InterstitialAd? _interstitialAd;
      bool _isAdLoaded = false;
    
      void interstitialAd() {
        InterstitialAd.load(
          adUnitId: Platform.isAndroid
              ? 'ca-app-pub-3940256099942544/1033173712'
              : 'ca-app-pub-3940256099942544/4411468910',
    
          request: AdRequest(),
          adLoadCallback: InterstitialAdLoadCallback(
            onAdLoaded: (ad) {
              _interstitialAd = ad;
              _isAdLoaded = true;
            },
            onAdFailedToLoad: (error) {
              print('Interstitial ad failed to load: $error');
            },
          ),
        );
      }
    
      void showInterstitialAd() {
        if (_isAdLoaded) {
          _interstitialAd?.fullScreenContentCallback;
          _interstitialAd?.show();
    
        } else {
          print('Interstitial ad is not yet loaded.');
        }
      }
    
      @override
      // TODO: implement onAdFailedToLoad
      FullScreenAdLoadErrorCallback get onAdFailedToLoad => throw UnimplementedError();
    
      @override
      // TODO: implement onAdLoaded
      GenericAdEventCallback<InterstitialAd> get onAdLoaded => throw UnimplementedError();
    }

## リワード


    import 'package:google_mobile_ads/google_mobile_ads.dart';
    import 'dart:io';
    
    class RewardedAdManager implements RewardedAdLoadCallback, FullScreenContentCallback {
    
      RewardedAd? _rewardedAd; // 広告オブジェクト
    
      // 広告のロード処理
      void loadRewardedAd() {
        RewardedAd.load(
          adUnitId: Platform.isAndroid
              ? 'ca-app-pub-3940256099942544/5224354917'
              : "ca-app-pub-3940256099942544/1712485313",
    
          request: AdRequest(),
          rewardedAdLoadCallback: RewardedAdLoadCallback(
            onAdLoaded: (ad) {
              _rewardedAd = ad; // 広告オブジェクトを保存
            },
            onAdFailedToLoad: (error) {
              print('Ad failed to load: $error');
            },
          ),
        );
      }
    
      // 広告の表示処理
      void showRewardedAd() {
    
        // 広告が表示されたときの処理
        _rewardedAd?.fullScreenContentCallback = FullScreenContentCallback(
          onAdShowedFullScreenContent: (ad) {
            print('Ad showed fullscreen content.');
          },
          // 広告が閉じられたときの処理
          onAdDismissedFullScreenContent: (ad) {
            print('Ad dismissed fullscreen content.');
            ad.dispose();
            loadRewardedAd();
          },
          onAdFailedToShowFullScreenContent: (ad, error) {
            print('Ad failed to show fullscreen content: $error');
            ad.dispose();
            loadRewardedAd();
          },
        );
    
        _rewardedAd?.setImmersiveMode(true);
        _rewardedAd?.show(
          // リワード広告再生時の処理
        onUserEarnedReward: (ad, reward) {
            print('User earned reward: ${reward.amount} ${reward.type}');
            // TODO: 報酬を与える処理を追加
    
          },
        );
      }
    
      // リワード広告のロードが成功した場合のコールバック
      @override
      void onRewardedAdLoaded(RewardedAd ad) {
        _rewardedAd = ad;
      }
    
      // リワード広告のロードが失敗した場合のコールバック
      @override
      void onRewardedAdFailedToLoad(LoadAdError error) {
        print('Rewarded ad failed to load: $error');
      }
    
      // リワード広告が閉じられた場合のコールバック
      @override
      void onRewardedAdDismissed(RewardedAd ad) {
        ad.dispose();
        loadRewardedAd();
      }
    
      // リワード広告が表示できなかった場合のコールバック
      @override
      void onRewardedAdFailedToShow(RewardedAd ad, AdError error) {
        ad.dispose();
        loadRewardedAd();
      }
    
      // 報酬広告が開いたときに実行されるコールバック
      @override
      void onRewardedAdOpened(RewardedAd ad) {
        print('Rewarded ad opened.');
      }
    
      // ユーザーが報酬を獲得したときに実行されるコールバック
      @override
      void onUserEarnedReward(RewardedAd ad, RewardItem reward) {
        print('User earned reward: ${reward.amount} ${reward.type}');
      }
    
      // 広告がクリックされたときに実行されるコールバック
      @override
      // TODO: implement onAdClicked
      GenericAdEventCallback? get onAdClicked => throw UnimplementedError();
    
      // フルスクリーン広告が閉じられたときに実行されるコールバック
      @override
      // TODO: implement onAdDismissedFullScreenContent
      GenericAdEventCallback? get onAdDismissedFullScreenContent => throw UnimplementedError();
    
      // 広告の読み込みに失敗したときに実行されるコールバック
      @override
      // TODO: implement onAdFailedToLoad
      FullScreenAdLoadErrorCallback get onAdFailedToLoad => throw UnimplementedError();
    
      // フルスクリーン広告の表示に失敗したときに実行されるコールバック
      @override
      // TODO: implement onAdFailedToShowFullScreenContent
      void Function(dynamic ad, AdError error)? get onAdFailedToShowFullScreenContent => throw UnimplementedError();
    
      // 広告が表示されたときに実行されるコールバック
      @override
      // TODO: implement onAdImpression
      GenericAdEventCallback? get onAdImpression => throw UnimplementedError();
    
      // 広告が読み込まれたときに実行されるコールバック
      @override
      // TODO: implement onAdLoaded
      GenericAdEventCallback<RewardedAd> get onAdLoaded => throw UnimplementedError();
    
      // フルスクリーン広告が表示されたときに実行されるコールバック
      @override
      // TODO: implement onAdShowedFullScreenContent
      GenericAdEventCallback? get onAdShowedFullScreenContent => throw UnimplementedError();
    
      // フルスクリーン広告が閉じられる直前に実行されるコールバック
      @override
      // TODO: implement onAdWillDismissFullScreenContent
      GenericAdEventCallback? get onAdWillDismissFullScreenContent => throw UnimplementedError();
    }

## リワードインタースティシャル

    import 'dart:io';
    import 'package:google_mobile_ads/google_mobile_ads.dart';
    
    class RewardedInterstitialAdManager implements RewardedInterstitialAdLoadCallback{
      // RewardedInterstitialAd クラスのインスタンスを保持する変数
      RewardedInterstitialAd? _rewardedInterstitialAd;
      // 広告の読み込みが完了しているかどうかを示すフラグ
      bool _isAdLoaded = false;
      // 広告の最大読み込み試行回数
      final int maxAdLoadRetries = 3;
      // 広告の読み込み試行間隔(秒単位)
      final int adLoadRetryTimeSeconds = 5;
    
      // 広告を読み込むメソッド
      void loadAd() {
        RewardedInterstitialAd.load(
          adUnitId: Platform.isAndroid
              ? 'ca-app-pub-3940256099942544/5354046379'
              : "ca-app-pub-3940256099942544/6978759866",
          request: AdRequest(),
          rewardedInterstitialAdLoadCallback: RewardedInterstitialAdLoadCallback(
            onAdLoaded: (ad) {
              print('Rewarded interstitial ad loaded.');
              _rewardedInterstitialAd = ad;
              _isAdLoaded = true;
            },
            onAdFailedToLoad: (error) {
              print('Rewarded interstitial ad failed to load: $error');
            },
          ),
        );
      }
    
      // 広告を表示するメソッド
      void showAd() {
        if (_isAdLoaded) {
          _rewardedInterstitialAd?.fullScreenContentCallback;
          _rewardedInterstitialAd?.show(onUserEarnedReward: (AdWithoutView ad, RewardItem reward) {
            // ユーザーが報酬を獲得した場合に呼び出されるコールバック
            print('User earned reward: ${reward.amount} ${reward.type}');
            // リワード処理をここに実装する
          });
        } else {
          print('Rewarded interstitial ad is not loaded.');
        }
      }
    
      //広告の読み込みに失敗した場合に呼び出されるコールバック
      @override
      // TODO: implement onAdFailedToLoad
      FullScreenAdLoadErrorCallback get onAdFailedToLoad => throw UnimplementedError();
    
      //広告の読み込みが完了した場合に呼び出されるコールバック
      @override
      // TODO: implement onAdLoaded
      GenericAdEventCallback<RewardedInterstitialAd> get onAdLoaded => throw UnimplementedError();
    }


## 【余談】画面の感じとか広告の感じとか

アプリ広告
<img width="300" alt="Screenshot_20230417_193558.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/ac24473b-9f98-04c2-2e79-dd7af331e6ad.png">
画面
<img width="300" alt="Screenshot_20230417_193356.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/dd6325e2-95e1-aec0-b08c-641816e39bb1.png">
インターステイシャル
<img width="300" alt="Screenshot_20230417_193523.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/7077da78-c0a9-ae2c-66bf-c61ada34b1cb.png">
リワード
<img width="300" alt="Screenshot_20230417_193552.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/df49b883-edec-680e-6c97-741a893f1321.png">