[Flutter] Admob

2023-03-18 hit count image

今回ブログポストではFlutterで生成したアプリにgoogle_mobile_adsパッケージを使ってAdmobの広告を表示する方法について説明します。

概要

このブログポストではgoogle_mobile_adsパッケージを使ってAdmobの広告を表示する方法について説明します。

このブログポストではAdmobのバナー広告を表示する方法について説明する予定です。ソースコードは下記のリンクで確認できます。

Admobの設定

FlutterプロジェクトでAdmobを使うためには、Admobのサービスを使う必要があります。

グーグルアドモブの会員登録

グーグルアドモブ(Google Admob)のサイトに移動して会員登録をします。一般的な会員登録やログインの手続きなので説明は省略します。

Admobの生成

グーグルアドモブ(Google Admob)の使い方についてみてみましょう。グーグルアドモブ(Google Admob)を使うために、グーグルアドモブ(Google Admob)のサイトに会員登録をしてログインをすると下記のような画面が確認できます。

signin google admob

下にあるGET STARTEDボタンを押してグーグルアドモブ(Google Admob)を使い始めます。

configure admob

既にアプリがマーケットに登録されたかを選べます。私たちはまだアプリを登録してない状態なのでNOを選択します。

configure app name on admob

グーグルアドモブ(Google Admob)を使うためアプリの名前を作成して使うプラットフォームを選択します。私たちはまず、iOSを選択して進めます。

completed to configure

グーグルアドモブ(Google Admob)の登録を完了しました。親切に下に次にやることについて説明が書いております。

  1. FlutterにAdmobを設定するため必要なApp IDをコピーします。
  2. 広告タイプ(ad unit)をグーグルアドモブ(Google Admob)で設定します。
  3. アプリをアプリストアに登録したらグーグルアドモブ(Google Admob)に連結する必要があります。

下にあるNEXT: CREATE AD UNITを押して広告のタイプを設定する画面に移動します。

select advertisement type

私たちは一旦バナー広告を使う予定です。Bannerの下にあるSELECTボタンを選択します。

input banner name

当該バナーの名前を設定します。グーグルアドモブ(Google Admob)のサービスで当該バナーを簡単に探すための名前なので、自分がわかりやすい名前で設定します。入力を完了したらCREATE AD UNITボタンを押して設定を完了します。

finished configuration

グーグルアドモブ(Google Admob)のバナーの設定を完了しました。次に出るApp IDとバナーのAd Unit IDをコピーしておきます。

アンドロイドも上と同じ方法でバナー広告を生成してApp IDとAd Unit IDを生成します。

プロジェクト生成

そしたらgoogle_mobile_adsパッケージを使ってAdmobの広告を表示するため、Flutterプロジェクトを新しく作ってみましょう。次のコマンドを実行してFlutterプロジェクトを生成します。

flutter create admob_example
cd admob_example

google_mobile_adsパッケージインストール

FlutterプロジェクトでAdmob広告を表示するためgoogle_mobile_adsのパッケージをインストールする必要があります。次のコマンドを実行してgoogle_mobile_adsをインストールします。

flutter pub add google_mobile_ads

App ID設定

次はgoogle_mobile_adsを使ってAdmobの広告を表示するため、iOS/AndroidにApp IDを設定する必要があります。

AndroidでApp IDの設定

アンドロイドでAdmobeのApp IDを設定するため、android/app/src/main/AndroidManifest.xmlファイルを開いて下記のように修正します。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.admob_example">
   <application
        ...>
        <meta-data
              android:name="com.google.android.gms.ads.APPLICATION_ID"
              android:value="[YOUR ANDROID APP ID]"/>
        ...
    </application>
</manifest>

iOSでApp IDの設定

iOSでAdmobのApp IDを設定するため、ios/Runner/Info.plistファイルを開いて下記のように修正します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  ...
  <key>GADApplicationIdentifier</key>
  <string>[YOUR iOS APP ID]</string>
  <key>LSRequiresIPhoneOS</key>
  <true/>
  <key>SKAdNetworkItems</key>
    <array>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>cstr6suwn9.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>4fzdc2evr5.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>2fnua5tdw4.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>ydx93a7ass.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>5a6flpkh64.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>p78axxw29g.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>v72qych5uu.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>c6k4g5qg8m.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>s39g8k73mm.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>3qy4746246.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>3sh42y64q3.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>f38h382jlk.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>hs6bdukanm.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>prcb7njmu6.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>v4nxqhlyqp.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>wzmmz9fp6w.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>yclnxrl5pm.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>t38b2kh725.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>7ug5zh24hu.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>9rd848q2bz.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>n6fk4nfna4.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>kbd757ywx3.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>9t245vhmpl.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>4468km3ulz.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>2u9pt9hc89.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>8s468mfl3y.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>av6w8kgt66.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>klf5c3l5u5.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>ppxm28t8ap.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>424m5254lk.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>uw77j35x4d.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>578prtvx9j.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>4dzt52r2t5.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>e5fvkxwrpn.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>8c4e2ghe7u.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>zq492l623r.skadnetwork</string>
      </dict>
      <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>3qcr597p9d.skadnetwork</string>
      </dict>
    </array>
</dict>
</plist>

google_mobile_adsの使い方

次はgoogle_mobile_adsを使ってAdmobeの広告を表示するため、main.dartファイルを開いて下記のように修正します。

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

const Map<String, String> UNIT_ID = kReleaseMode
    ? {
        'ios': '[YOUR iOS AD UNIT ID]',
        'android': '[YOUR ANDROID AD UNIT ID]',
      }
    : {
        'ios': 'ca-app-pub-3940256099942544/2934735716',
        'android': 'ca-app-pub-3940256099942544/6300978111',
      };

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    TargetPlatform os = Theme.of(context).platform;

    BannerAd banner = BannerAd(
      listener: BannerAdListener(
        onAdFailedToLoad: (Ad ad, LoadAdError error) {},
        onAdLoaded: (_) {},
      ),
      size: AdSize.banner,
      adUnitId: UNIT_ID[os == TargetPlatform.iOS ? 'ios' : 'android']!,
      request: AdRequest(),
    )..load();

    return Scaffold(
      appBar: AppBar(
        title: Text('Admob'),
      ),
      body: Center(
        child: Container(
          height: 50,
          child: AdWidget(
            ad: banner,
          ),
        ),
      ),
    );
  }
}

ソースコードを一つづつ詳しくみてみましょう。

import 'package:flutter/foundation.dart';

Admobの広告は開発環境の場合、自分のAD UNIT IDを使うとダメです。自分の開発環境で自分のAD UNIT IDを使う場合、実際の広告トラピックではなく不正トラピックになるので、いっぱい使うと広告掲載をブロックされる可能性があります。したがって、今回の例ではkReleaseModeを使って現在実行してる環境がdebugreleaseかを区別する予定です。kReleaseModeを使うためにはfoundation.dartを使う必要があります。

import 'package:google_mobile_ads/google_mobile_ads.dart';

google_mobile_adsを使うため、追加します。

const Map<String, String> UNIT_ID = kReleaseMode
    ? {
        'ios': '[YOUR iOS AD UNIT ID]',
        'android': '[YOUR ANDROID AD UNIT ID]',
      }
    : {
        'ios': 'ca-app-pub-3940256099942544/2934735716',
        'android': 'ca-app-pub-3940256099942544/6300978111',
      };

kReleaseModeを使って現在の環境がreleaseの場合、私たちが作ったAD UNIT IDを使えるように設定しました。そうでない場合は、Admobが提供するテスト用のAD UNIT IDを使えるようにしました。

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();

  runApp(MyApp());
}

google_mobile_adsを使ってAdmobの広告を表示するためMobileAdsを初期化する必要があります。WidgetsFlutterBinding.ensureInitialized();を使ってFlutterが初期化されたかを確認した後、MobileAds.instance.initialize();をコールしてMobileAdsを初期化します。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
}

簡単なサンプルコードを作成するためStatelessウィジェットを生成しました。

次は実際バナー広告を表示するソースコードを詳しくみてみましょう。

@override
Widget build(BuildContext context) {
  TargetPlatform os = Theme.of(context).platform;

  BannerAd banner = BannerAd(
    listener: BannerAdListener(
      onAdFailedToLoad: (Ad ad, LoadAdError error) {},
      onAdLoaded: (_) {},
    ),
    size: AdSize.banner,
    adUnitId: UNIT_ID[os == TargetPlatform.iOS ? 'ios' : 'android']!,
    request: AdRequest(),
  )..load();

  return Scaffold(
    appBar: AppBar(
      title: Text('Admob'),
    ),
    body: Center(
      child: Container(
        height: 50,
        child: AdWidget(
          ad: banner,
        ),
      ),
    ),
  );
}

各プラットフォームよりAD UNIT IDが違うので、現在のFlutterが実行されてるプラットフォームを識別する必要があります。このためTargetPlatformを使います。

TargetPlatform os = Theme.of(context).platform;

そしてgoogle_mobile_adsで提供されてるBannerAdクラスを使ってバナー広告を生成しましたし、Cascade operatorを使って生成と同時にload()関数を実行して広告を取ってきました。

BannerAd banner = BannerAd(
  listener: BannerAdListener(
    onAdFailedToLoad: (Ad ad, LoadAdError error) {},
    onAdLoaded: (_) {},
  ),
  size: AdSize.banner,
  adUnitId: UNIT_ID[os == TargetPlatform.iOS ? 'ios' : 'android']!,
  request: AdRequest(),
)..load();

この時、AdListenerを使って広告に関するイベントにコールバック関数を登録することができまし、AdRequestの色んなパラメータを使ってもっと効率的な広告を表示することができます。

このように生成した広告をAdWidgetを使って画面に表示します。

AdWidget(
  ad: banner,
)

現在の例題は簡単に広告を表示する方法をStatelessウィジェットを使ってみてみました。もし、Statefulウィジェットを使ったら、次のようにウィジェットが消える時、広告も削除しなきゃならないです。

@override
void dispose() {
  super.dispose();
  _banner.dispose();
}

イシュー

google_mobile_adsで広告を表示する時経験したイシューを共有します。

await MobileAds.instance.initialize()

私はgoogle_mobile_adsのバージョンを0.13.4で設定して使っています。このバージョンより上のバージョンを使う場合、アンドロイドの一部端末でawait MobileAds.instance.initialize()部分が終わらなくなって、アプリが強制終了される問題が発生しています。

したがって、私はまだ0.13.4でバージョンを固定して使っています。

dependencies:
  ...
  google_mobile_ads: 0.13.4

Ad failed to load : 3

開発中のアプリをエミューレーターでtest unit idを使ってバーナー広告を表示すると、Ad failed to load : 3のエラーメッセージが出って、広告が表示されない問題があります。

私はこの問題を解決するため、開発中のアプリでもtest unit idではなく実際のunit idを使っています。実際のunit idを使ってもTest modeと一緒に問題なく広告が表示されることを確認しました。

Test modeが表示されてるので、不正広告トラピックではないと思ってるので、問題ないと判断して開発する時も実際のunit idを使っています。

もし、実際のunit idを使っても同じエラーメッセージが発生すると、そのアプリを実際のデバイスに上げて、実際トラピックを発生してみます。Ad failed to load : 3メッセージはエラーではなく広告が準備できてたいことを意味します。したがって、設定は問題ないことです。しかし、色んな理由で画面に表示する広告がまだ準備できてないことを意味します。実際のトラピックも広告を準備することに影響があるので、実際デバイスでアプリを動作して実際トラピックを発生してみてください。

完了

これでgoogle_mobile_adsパッケージを使ってAdmobの広告を表示する方法についてみてみました。今から皆さんも、皆さんのアプリへ広告を追加して履歴をだしてみてください!

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts