こんにちは。個人アプリ開発の醍醐味である広告収入ですが、意外と表示方法に関する情報が少ない気がします。バナー広告を使った方法は散見されますが、今回はインタースティシャル広告を表示してみたいと思います。ここまで長かった。。。
Admob準備
まずはAdmob管理画面でアプリを追加します。ストアにて公開していない状態でも大丈夫です。iOS,Androidそれぞれ作成しましょう。その後、それぞれでインタースティシャル広告を作成しておきます。動画を流さない様にとか選択できるみたいですね。
作成すると、アプリIDと広告IDが表示されるので控えておいてください。
flutter準備(共通)
まずはyamlにパッケージを追加しましょう。公式は勿論、非公式のパッケージも存在します。今回は公式を利用。firebase_admobです。dependenciesに追加してください。バージョンは実装時の最新値を使った方が良いでしょう。
dependencies:
firebase_admob: ^0.10.2
尚、いろいろ調べていましたがgoogleは非公式のadmobパッケージを推奨していない模様。バグ等によって不正なリクエストが起きた際、アカウント停止の可能性もあるからとのことです。確かにflutterのUI描画サイクルを考えると、考えられない話でもないので私は無難に公式を使います。
iOS準備
まず、ios/Runner/info.plistを開き、以下を追加。
<key>GADApplicationIdentifier</key>
<string>admobのアプリID</string>
アプリIDはAdmobの管理画面で確認できます。当たり前ですがiOSアプリのIDを持って来てくださいね!
Android準備
Androidは、android/app/src/main/kotlin/アプリのバンドルID〜と進んだ先にあるAndroidManifest.xmlに以下を追加します。
<manifest>
<application>
〜〜〜〜〜元からある記述〜〜〜〜〜〜
<!-- TODO: Replace with your real AdMob app ID -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="admobのアプリID"/>
</application>
</manifest>
</application>タグ終わりを目印に追加すると混乱せずに作業できます。valueにAdmobから取得したAndroidアプリのアプリIDを記述してください。
flutter側(共通)
それぞれのOSでGoogleの設定ファイルをダウンロードし、適当な場所において置く必要があります。こちらを参考に準備してください。その1がiOS,その2がAndroidです。
そしてついに広告の表示部分。以下のコードを記述してください。公式ページのものベースです。一部コードは非推奨となっていたので減らしてます。また、テスト広告を表示する様になってます。
MobileAdTargetingInfo targetingInfo = MobileAdTargetingInfo(
keywords: <String>['flutterio', 'beautiful apps'],
contentUrl: 'https://flutter.io',
childDirected: false,
testDevices: <String>[], // Android emulators are considered test devices
);
InterstitialAd myInterstitial = InterstitialAd(
// Replace the testAdUnitId with an ad unit id from the AdMob dash.
// https://developers.google.com/admob/android/test-ads
// https://developers.google.com/admob/ios/test-ads
adUnitId: InterstitialAd.testAdUnitId,
targetingInfo: targetingInfo,
listener: (MobileAdEvent event) {
print("InterstitialAd event is $event");
},
);
myInterstitial
..load()
..show(
anchorType: AnchorType.bottom,
anchorOffset: 0.0,
horizontalCenterOffset: 0.0,
);
ここでFlutterに慣れている人は気付くかと思いますが、widgetとは関係ないUI層で表示されます。アプリの画面の一つ手前側に、別階層として表示されるイメージです。これはバナー広告等も同じだそうで、今回は全画面広告なのであまり意識する必要はありませんが、既存のコンテンツと組み合わせて配置する場合は一手間必要です。
また、このままだと広告閉じるボタンがステータスバーに隠れてしまい押せません。調べたところ、バグです。この隠れてしまう挙動はインタースティシャル広告だけでなく、一部のリワード広告でも発生する様子。
対処法はissueにも上がってましたが、これが今のところ一番しっくり来ました。
InterstitialAd myInterstitial = InterstitialAd(
// Replace the testAdUnitId with an ad unit id from the AdMob dash.
// https://developers.google.com/admob/android/test-ads
// https://developers.google.com/admob/ios/test-ads
adUnitId: InterstitialAd.testAdUnitId,
targetingInfo: targetingInfo,
listener: (MobileAdEvent event) {
if (event == MobileAdEvent.loaded)
SystemChrome.setEnabledSystemUIOverlays([]);
else if (event == MobileAdEvent.closed)
SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
},
);
listnerに、loadedの時はステータスバーを非表示に、closedの時はステータスバーを表示する様に登録しています。要件によってはこれでカバーできないかもしれませんが、その辺りは創意工夫を。。。
テスト表示完了後、本番用IDセット
必ず「テスト用広告が意図されたタイミングで表示されるか」を確認してから本番用IDで試しましょう。flutterは宣言型言語の様にコードが再読み込みされますから、意図しないリクエストが短時間でかなりの数繰り返されることも考えられます。その場合、不正利用と見做される可能性もありますので気をつけてください。
以下の様なメソッドを用意します。
static String getAppId() {
if (Platform.isIOS) {
return '';
} else if (Platform.isAndroid) {
return '';
}
return null;
}
static String getInterstitialAdUnitId() {
if (Platform.isIOS) {
return '';
} else if (Platform.isAndroid) {
return '';
}
return null;
}
iOSとAndroidそれぞれにあったIDを返すだけですね。
getInterstitialAdUnitId()をInterstitialAd.testAdUnitIdと置き換えてください。
また、以下の様な初期化処理も行う必要があります。
FirebaseAdMob.instance.initialize(appId: getAppId());
これらをfactoryとか使って良い感じに実装してください。(疲れたので参考コードなし)
とっても長い道のり。。。
細かい解説(ちょっとだけ)
MobileAdTargetingInfoのコンストラクタでkeywordsとありますが、ここにはあなたのアプリと関連性のあるキーワードを記述しておきます。効果の程は未検証です。
閉じるボタンがうまく機能しなくなるバグはノッチが存在するiPhoneシリーズの他、Androidでも一部機種で発生する模様なので、複数のエミュレータで試してみる方が良いかもしれません。
終わりに
ここまで無事に辿り着けた方、本当にお疲れ様でした。大変だった分、達成感も感無量なことでしょう。また、広告表示を実装するということはアプリ開発も大詰めでしょうし。
個人的には大変だったものの、Xamarinよりはわかりやすい感じでしたね。Xamarinで広告表示を実装した時は謎エラー出まくりでしたから。。。(Xamarin使いあるある)
flutterでの開発はエラーが出たとしても基本的に原因がわかりやすく、その分対処方法も探しやすい。特に個人開発している自分にはこれがありがたいです。
初心者向けflutter講座サービス始めようかな。。。