くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

FlutterのAdmobでリワード広告を表示する

前回の続き。バナー広告は表示できたので、
リワード広告も試してみたときの備忘録(*´ω`*)

www.memory-lovers.blog

リワード広告とは

長めの動画広告を見ると、ユーザが報酬を受け取れるタイプの広告

リワード広告とリワードインタースティシャル広告(β版)の2つがあり、 こんな違いがある。プログラム側は同じ感じっぽい。

  • リワード広告
    • スキップ不可、ユーザのオプトインが必要
  • リワードインタースティシャル広告(β版)
    • スキップ可能、ユーザのオプトイン不要

リワードインタースティシャル広告のチュートリアル動画に、
詳しい説明やリワード広告との比較もあるので参考になる。

どちらとも

  • すべてのアプリコンテンツの上にオーバーレイとして表示され、静的に配置
  • そのため、Flutterウィジェットツリーに追加することはできない

という感じなので、バナーのように埋め込むことはできず、
表示を呼び出すと、全画面サイズで最前面に表示される。

リワード広告の実装

公式ドキュメントだとこのあたり

バナー広告だと、

  • BannerAdを作成
  • BannerAd().load()で読み込み開始
  • AdWidgetで広告の表示

という流れだったけど、
リワード広告では、

  • RewardedAd.load()で作成と読み込み
  • RewardedAd.show()で表示

という感じになる。

テスト用の広告ユニットID

Android: ca-app-pub-3940256099942544/5224354917
iOS:     ca-app-pub-3940256099942544/1712485313

広告の読み込み

広告の読み込みはこんな感じ。

class RewardedExampleState extends State<RewardedExample> {
  RewardedAd? _rewardedAd;

  final adUnitId = Platform.isAndroid
    ? 'ca-app-pub-3940256099942544/5224354917'
    : 'ca-app-pub-3940256099942544/1712485313';

  /// Loads a rewarded ad.
  void loadAd() {
    RewardedAd.load(
      adUnitId: adUnitId,
      request: const AdRequest(),
      adLoadCallback: RewardedAdLoadCallback(
        // 読み込み完了時
        onAdLoaded: (ad) {
          debugPrint('$ad loaded.');
          // 受け取ったRewardedAd adを保存しておく
          _rewardedAd = ad;
        },
        // 読み込みエラー時
        onAdFailedToLoad: (LoadAdError error) {
          debugPrint('RewardedAd failed to load: $error');
        },
      ));
  }
}

読み込みが完了すると、RewardedAdLoadCallbackonAdLoadedが呼ばれる。

バナー広告のBannerAdListenerとは異なり、
読み込みに関するコールバックのみで、表示に関するコールバックは別。

表示に関するコールバックについては、FullScreenContentCallbackを使う
ちょっと長いけど、onAdLoadedで受け取ったRewardedAd adに対して、
ad.fullScreenContentCallbackに設定していく。

adLoadCallback: RewardedAdLoadCallback(
  // 読み込み完了時
  onAdLoaded: (ad) {
    ad.fullScreenContentCallback = FullScreenContentCallback(
      // 広告が表示されたとき
      onAdShowedFullScreenContent: (ad) {},
      // インプレッションが発生したとき
      onAdImpression: (ad) {},
      // 広告の表示に失敗したとき or 再度表示しようとしたとき
      onAdFailedToShowFullScreenContent: (ad, err) {
        // 失敗したら、広告を破棄する
        ad.dispose();
      },
      // 広告が閉じられたとき
      onAdDismissedFullScreenContent: (ad) {
        // 見終わったら、広告を破棄する
        ad.dispose();
      },
      // 広告をクリックしたとき
      onAdClicked: (ad) {});

    debugPrint('$ad loaded.');
    // 受け取ったRewardedAd adを保存しておく
    _rewardedAd = ad;
  },
)

バナー広告と異なり、失敗したり、見終わったりしたら、
ad.dispose()を呼び出して、広告を破棄しておく。

広告の表示

表示するときはこんな感じ。

動画を視聴し終わって、報酬を得たときの処理は、
onUserEarnedRewardのコールバックを使って行う感じ。

_rewardedAd.show(onUserEarnedReward: (AdWithoutView ad, RewardItem rewardItem) {
  // 動画を見たユーザに、報酬や特典を付与する
});

また、RewardedAdは1度しか表示できず、再度表示しようとすると、
FullScreenContentCallbackonAdFailedToShowFullScreenContentが呼ばれる。

なので、見終わったらちゃんと破棄して、
その都度、リワード広告の読み込みを行う必要がある。

実装時の注意

注意事項などに関するポリシーはこのあたり

特に気をつけないとと思った点は以下

  • 各リワード広告が表示される前に、報酬の要件となるユーザー行動と提供される報酬を明確かつ正確に開示する必要がある
    • 何をしたら、何をもらえるのかを事前に表示しないといけない(動画を見たらポイント2倍など)
  • 能動的かつ明確にオプトイン(「はい」または「同意する」というボタンをタップするなど)したユーザーにのみ配信する必要がある
    • ユーザ自身の行動で再生を開始しないといけない(自動生成はNG)
  • リワード広告の操作をユーザーに強制してないけない
    • 動画を見ないと次に進めない/ダイアログが消えないなどはNG
  • リワード広告が視聴されなかった際に、通常の使用を妨げてはなりません
    • 見ないと不便になるなどはNG(あくまで特典/報酬の付与)
  • 提供される報酬について説明する以外の目的で、ユーザーの誤解を招く、
    またはユーザーに特定の選択を促す文言やアイコンを使用することはできません
    • 「この広告を視聴してビジネスをサポートしましょう」などはNG
  • リワード広告を見たユーザに必ず報酬を付与する必要がある

以上!! これでいろいろできる気がする(*´ω`*)

参考にしたサイトさま