Flutter 앱에 AdMob 광고 추가

1. 소개

빌드할 내용

이 Codelab에서는 플레이어가 그림의 이름을 추측할 수 있는 게임인 Awesome Drawing Quiz라고 하는 앱에 배너 광고, 전면 광고 및 보상형 광고를 추가하는 방법을 안내합니다.

이 Codelab을 진행하는 동안 문제(코드 버그, 문법 오류, 불분명한 문구)가 발생하는 경우 Codelab 왼쪽 하단에 있는 Report a mistake 링크를 통해 문제를 신고해 주세요.

과정 내용

  • Google 모바일 광고 AdMob 플러그인을 구성하는 방법
  • Flutter 앱에서 배너 광고, 전면 광고 및 보상형 광고를 구현하는 방법

필요한 사항

  • Android 스튜디오 4.1 이상
  • Xcode 12 이상(iOS 개발용)

고객님의 AdMob 이용 경험 수준을 어떻게 평가하시겠어요?

초급 중급 고급

고객님의 Flutter 이용 경험 수준을 어떻게 평가하시겠어요?

초급 중급 고급

2. Flutter 개발 환경 설정

이 실습을 완료하려면 Flutter SDK 및 편집기라는 두 가지 소프트웨어가 필요합니다.

다음 기기 중 하나를 사용하여 이 Codelab을 실행할 수 있습니다.

  • 컴퓨터에 연결되어 있으며 개발자 모드로 설정된 실제 Android 또는 iOS 기기
  • iOS 시뮬레이터(Xcode 도구 설치 필요)
  • Android Emulator(Android 스튜디오 설정 필요)
  • 브라우저(디버깅 시 Chrome 필요)
  • Windows, Linux 또는 macOS 데스크톱 애플리케이션. 배포에 사용할 플랫폼에서 개발해야 합니다. 따라서 Windows 데스크톱 앱을 개발하려면 적절한 빌드 체인에 액세스할 수 있도록 Windows에서 개발해야 합니다. docs.flutter.dev/desktop에 운영체제별 요구사항이 자세히 설명되어 있습니다.

코드 다운로드

zip 파일을 다운로드한 후 콘텐츠를 추출하세요. admob-ads-in-flutter-master라는 폴더가 생성됩니다.

또는 명령줄에서 GitHub 저장소를 클론할 수 있습니다.

$ git clone https://github.com/googlecodelabs/admob-ads-in-flutter

저장소에는 다음 두 폴더가 포함됩니다.

  • android_studio_folder.pngstarter — 이 Codelab에서 빌드할 시작 코드
  • android_studio_folder.pngcomplete — 이 Codelab을 위해 완료된 코드

3. AdMob 앱 및 광고 단위 설정

Flutter는 멀티 플랫폼 SDK이므로 AdMob에서 Android 및 iOS 모두를 위한 앱과 광고 단위를 추가해야 합니다.

Android용으로 설정

Android용으로 설정하려면 Android 앱을 추가하고 광고 단위를 만들어야 합니다.

Android 앱 추가

  1. AdMob 콘솔의 앱 메뉴에서 앱 추가를 클릭합니다.
  2. 앱을 Google Play 또는 App Store에 게시하셨나요?라는 질문이 표시되면 아니요를 클릭합니다.
  3. 앱 이름 입력란에 Awesome Drawing Quiz를 입력하고 Android를 플랫폼으로 선택합니다.

ddafee37a6f92229.png

  1. 이 Codelab을 완료하기 위해 사용자 측정항목을 사용 설정하지 않아도 됩니다. 하지만 그렇게 하면 사용자 행동을 더 자세히 파악할 수 있습니다. 추가를 클릭하여 절차를 완료합니다.

b918bf44362813a9.png

광고 단위 만들기

AdMob에 광고 단위를 추가하는 방법은 다음과 같습니다.

  1. AdMob 콘솔의 앱 메뉴에서 Awesome Drawing Quiz를 선택합니다.
  2. 광고 단위 메뉴를 클릭합니다.

배너 광고

  1. 광고 단위 추가 버튼을 클릭합니다.
  2. 배너 광고를 형식으로 선택합니다.
  3. 광고 단위 이름 입력란에 android-adq-banner를 입력합니다.
  4. 광고 단위 만들기를 클릭하여 절차를 완료합니다.

전면 광고

  1. 광고 단위 추가 버튼을 클릭합니다.
  2. 전면 광고를 형식으로 선택합니다.
  3. 광고 단위 이름 입력란에 android-adq-interstitial을 입력합니다.
  4. 광고 단위 만들기를 클릭하여 절차를 완료합니다.

보상형 광고

  1. 광고 단위 추가 버튼을 클릭합니다.
  2. 보상형 광고를 형식으로 선택합니다.
  3. 광고 단위 이름 입력란에 android-adq-rewarded를 입력합니다.
  4. 리워드 설정의 기본값을 그대로 둡니다.
  5. 광고 단위 만들기를 클릭하여 절차를 완료합니다.

일반적으로 새 광고 단위에서 광고를 게재하는 데는 몇 시간이 소요됩니다.

광고의 작동 방식을 즉시 테스트하려면 Android 앱 ID/광고 단위 ID 및 iOS 앱 ID/광고 단위 ID 표에 표시된 테스트 앱 ID 및 광고 단위 ID를 사용하세요.

iOS용으로 설정

iOS용으로 설정하려면 iOS 앱을 추가하고 광고 단위를 만들어야 합니다.

iOS 앱 추가

  1. AdMob 콘솔의 앱 메뉴에서 앱 추가를 클릭합니다.
  2. 앱을 Google Play 또는 App Store에 게시하셨나요?라는 질문이 표시되면 아니요를 클릭합니다.
  3. 앱 이름 입력란에 Awesome Drawing Quiz를 입력하고 iOS를 플랫폼으로 선택합니다.

93e7f9f114232402.png

  1. 이 Codelab을 완료하기 위해 사용자 측정항목을 사용 설정하지 않아도 됩니다. 하지만 그렇게 하면 사용자 행동을 더 자세히 파악할 수 있습니다. 추가를 클릭하여 절차를 완료합니다.

b918bf44362813a9.png

광고 단위 만들기

광고 단위를 추가하는 방법은 다음과 같습니다.

  1. AdMob 콘솔의 앱 메뉴에서 Awesome Drawing Quiz 앱을 선택합니다.
  2. 광고 단위 메뉴를 클릭합니다.

배너 광고

  1. 광고 단위 추가 버튼을 클릭합니다.
  2. 배너 광고를 형식으로 선택합니다.
  3. 광고 단위 이름 입력란에 ios-adq-banner를 입력합니다.
  4. 광고 단위 만들기를 클릭하여 절차를 완료합니다.

전면 광고

  1. 광고 단위 추가 버튼을 클릭합니다.
  2. 전면 광고를 형식으로 선택합니다.
  3. 광고 단위 이름 입력란에 ios-adq-interstitial을 입력합니다.
  4. 광고 단위 만들기를 클릭하여 절차를 완료합니다.

보상형 광고

  1. 광고 단위 추가 버튼을 클릭합니다.
  2. 보상형 광고를 형식으로 선택합니다.
  3. 광고 단위 이름 입력란에 ios-adq-rewarded를 입력합니다.
  4. 리워드 설정의 기본값을 그대로 둡니다.
  5. 광고 단위 만들기를 클릭하여 절차를 완료합니다.

일반적으로 새 광고 단위에서 광고를 게재하는 데는 몇 시간이 소요됩니다.

광고의 작동 방식을 즉시 테스트하려면 다음 표에 표시된 테스트 앱 ID 및 광고 단위 ID를 사용하세요.

선택사항: 테스트 AdMob 앱 및 광고 단위 사용

새 애플리케이션과 광고 단위를 직접 만드는 대신 Codelab을 따르려면 다음 표에 나와 있는 테스트 AdMob 앱 ID와 광고 단위 ID를 사용하면 됩니다.

Android 앱 ID/광고 단위 ID

항목

앱 ID/광고 단위 ID

AdMob 앱 ID

ca-app-pub-3940256099942544~3347511713

배너 광고

ca-app-pub-3940256099942544/6300978111

전면 광고

ca-app-pub-3940256099942544/1033173712

보상형 광고

ca-app-pub-3940256099942544/5224354917

iOS 앱 ID/광고 단위 ID

항목

앱 ID/광고 단위 ID

AdMob 앱 ID

ca-app-pub-3940256099942544~1458002511

배너 광고

ca-app-pub-3940256099942544/2934735716

전면 광고

ca-app-pub-3940256099942544/4411468910

보상형 광고

ca-app-pub-3940256099942544/1712485313

테스트 광고에 대한 자세한 내용은 Android 테스트 광고 및 iOS 테스트 광고 개발자 문서를 참고하세요.

4. Google 모바일 광고 Flutter 플러그인 추가

Flutter에서는 플러그인을 사용하여 광범위한 플랫폼별 서비스에 대한 액세스를 제공합니다. 플러그인을 사용하면 각 플랫폼의 서비스와 API에 액세스할 수 있습니다.

google_mobile_ads 플러그인은 AdMob API을 사용하여 배너 광고, 전면 광고, 보상형 광고 및 네이티브 광고의 로드 및 표시를 지원합니다.

Flutter는 멀티 플랫폼 SDK이므로 google_mobile_ads 플러그인은 iOS와 Android 모두에 적용할 수 있습니다. 따라서 Flutter 앱에 플러그인을 추가하면 AdMob 인라인 광고 앱의 Android 및 iOS 버전 모두에서 사용됩니다.

Google 모바일 광고 플러그인을 종속 항목으로 추가

AdMob 인라인 광고 프로젝트에서 AdMob API에 액세스하려면 google_mobile_ads를 프로젝트의 루트에 있는 pubspec.yaml 파일에 종속 항목으로 추가하세요.

pubspec.yaml

...
environment:
  # TODO: Update the minimum sdk version to 2.12.0 to support null safety.
  sdk: ">=2.17.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  google_fonts: ^3.0.1

  # TODO: Add google_mobile_ads as a dependency
  google_mobile_ads: ^1.2.0

...

Pub get을 클릭하여 Awesome Drawing Quiz 프로젝트에 플러그인을 설치합니다.

9ce73858eedbd8fc.png

AndroidManifest.xml 업데이트(Android)

  1. Android 스튜디오에서 android/app/src/main/AndroidManifest.xml 파일을 엽니다.
  2. 이름이 com.google.android.gms.ads.APPLICATION_ID인 <meta-data> 태그를 추가하여 AdMob 앱 ID를 추가합니다. 예를 들어 AdMob 앱 ID가 ca-app-pub-3940256099942544~3347511713인 경우 AndroidManifest.xml 파일에 다음 행을 추가해야 합니다.

AndroidManifest.xml

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

</manifest>

Info.plist 업데이트(iOS)

  1. Android 스튜디오에서 ios/Runner/Info.plist 파일을 엽니다.
  2. AdMob 앱의 문자열 값이 포함된 GADApplicationIdentifier 키를 추가합니다. 예를 들어 AdMob 앱 ID가 ca-app-pub-3940256099942544~1458002511인 경우 Info.plist 파일에 다음 행을 추가해야 합니다.

ios/Runner/Info.plist

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

5. 광고의 도우미 클래스 추가

lib 디렉터리에 이름이 ad_helper.dart인 새 파일을 엽니다. 그런 다음 Android 및 iOS의 AdMob 앱 ID와 광고 단위 ID를 제공하는 AdHelper 클래스를 구현합니다.

AdMob 앱 ID(ca-app-pub-xxxxxx~yyyyy)와 광고 단위 ID(ca-app-pub-xxxxxxx/yyyyyyyy)를 이전 단계에서 만든 ID로 교체해야 합니다.

lib/ad_helper.dart

import 'dart:io';

class AdHelper {

  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return '<YOUR_ANDROID_BANNER_AD_UNIT_ID>';
    } else if (Platform.isIOS) {
      return '<YOUR_IOS_BANNER_AD_UNIT_ID>';
    } else {
      throw UnsupportedError('Unsupported platform');
    }
  }

  static String get interstitialAdUnitId {
    if (Platform.isAndroid) {
      return '<YOUR_ANDROID_INTERSTITIAL_AD_UNIT_ID>';
    } else if (Platform.isIOS) {
      return '<YOUR_IOS_INTERSTITIAL_AD_UNIT_ID>';
    } else {
      throw UnsupportedError('Unsupported platform');
    }
  }

  static String get rewardedAdUnitId {
    if (Platform.isAndroid) {
      return '<YOUR_ANDROID_REWARDED_AD_UNIT_ID>';
    } else if (Platform.isIOS) {
      return '<YOUR_IOS_REWARDED_AD_UNIT_ID>';
    } else {
      throw UnsupportedError('Unsupported platform');
    }
  }
}

테스트 AdMob 앱 ID와 테스트 광고 단위 ID를 사용하려면 다음 코드 스니펫을 사용하세요.

lib/ad_helper.dart

import 'dart:io';

class AdHelper {

  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return 'ca-app-pub-3940256099942544/6300978111';
    } else if (Platform.isIOS) {
      return 'ca-app-pub-3940256099942544/2934735716';
    } else {
      throw new UnsupportedError('Unsupported platform');
    }
  }

  static String get interstitialAdUnitId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544/1033173712";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544/4411468910";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get rewardedAdUnitId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544/5224354917";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544/1712485313";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }
}

6. Google 모바일 광고 SDK 초기화

광고를 로드하기 전에 Google 모바일 광고 SDK를 초기화해야 합니다. lib/home_route.dart 파일을 열고 홈페이지가 로드되기 전에 SDK가 초기화되도록 _initGoogleMobileAds()를 수정합니다.

초기화가 완료된 후 SDK 초기화 결과를 얻으려면 _initGoogleMobileAds() 메서드의 반환 유형을 Future<dynamic>에서 Future<InitializationStatus>로 변경해야 합니다.

home_route.dart

// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'package:flutter/material.dart';

...

class HomeRoute extends StatelessWidget {

  ...

  Future<InitializationStatus> _initGoogleMobileAds() {
    // TODO: Initialize Google Mobile Ads SDK
    return MobileAds.instance.initialize();
  }
}

7. 배너 광고 추가

이 섹션에서는 다음 스크린샷에 표시된 대로 게임 화면의 상단에 배너 광고를 표시합니다.

276b4cfa283ea6c7.png

  1. lib/game_route.dart 파일을 열고 ad_manager.dart를 가져옵니다.
  2. 다음 행을 추가하여 ad_helper.dart 및 google_mobile_ads.dart를 가져옵니다.

lib/game_route.dart

...

// TODO: Import ad_helper.dart
import 'package:awesome_drawing_quiz/ad_helper.dart';

// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';

class GameRoute extends StatefulWidget {
  ...
}
  1. _GameRouteState 클래스에서 배너 광고를 위해 다음 구성원을 추가합니다.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _bannerAd
  BannerAd? _bannerAd;

  ...
}
  1. initState() 메서드에서 320x50 배너(AdSize.banner)를 위한 BannerAd를 만들어 로드합니다. 광고과 로드될 때 UI(setState())를 업데이트하기 위해 광고 이벤트 리스너가 구성됩니다.

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Load a banner ad
  BannerAd(
    adUnitId: AdHelper.bannerAdUnitId,
    request: AdRequest(),
    size: AdSize.banner,
    listener: BannerAdListener(
      onAdLoaded: (ad) {
        setState(() {
          _bannerAd = ad as BannerAd;
        });
      },
      onAdFailedToLoad: (ad, err) {
        print('Failed to load a banner ad: ${err.message}');
        ad.dispose();
      },
    ),
  ).load();
}
  1. 사용 가능한 경우 배너 광고를 표시하도록 build() 메서드를 수정합니다.

lib/game_route.dart

@override
Widget build(BuildContext context) {
  return Scaffold(
    ...
    body: SafeArea(
      child: Stack(
        children: [
          Center(
            ...
          ),
          // TODO: Display a banner when ready
          if (_bannerAd != null)
            Align(
              alignment: Alignment.topCenter,
              child: Container(
                width: _bannerAd!.size.width.toDouble(),
                height: _bannerAd!.size.height.toDouble(),
                child: AdWidget(ad: _bannerAd!),
              ),
            ),
        ],
      ),
    ),
    ...
  );
}
  1. dispose() 콜백 메서드에서 BannerAd.dispose() 메서드를 호출하여 BannerAd 객체와 연결된 리소스를 릴리스합니다.

lib/game_route.dart

@override
void dispose() {
  // TODO: Dispose a BannerAd object
  _bannerAd?.dispose();

  ...

  super.dispose();
}

준비가 끝났습니다. 프로젝트를 실행하고 새 게임을 시작합니다. 광고가 로드된 후 화면의 상단에 배너 광고가 표시됩니다.

276b4cfa283ea6c7.png

8. 전면 광고 추가

이 섹션에서는 게임(총 5단계)이 완료된 후 전면 광고를 표시합니다.

  1. lib/game_route.dart 파일을 엽니다.
  2. _GameRouteState 클래스에서 전면 광고를 위해 다음 구성원과 메서드를 추가합니다.

광고가 준비되었는지 확인하고(onAdLoaded() 및 onAdFailedToLoad()) 광고가 닫힌 경우(onAdDismissedFullScreenContent()) 앱의 홈 화면을 표시하기 위해 광고 이벤트 리스너가 구성됩니다

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _interstitialAd
 InterstitialAd? _interstitialAd;

  // TODO: Implement _loadInterstitialAd()
  void _loadInterstitialAd() {
    InterstitialAd.load(
      adUnitId: AdHelper.interstitialAdUnitId,
      request: AdRequest(),
      adLoadCallback: InterstitialAdLoadCallback(
        onAdLoaded: (ad) {
          ad.fullScreenContentCallback = FullScreenContentCallback(
            onAdDismissedFullScreenContent: (ad) {
              _moveToHome();
            },
          );

          setState(() {
            _interstitialAd = ad;
          });
        },
        onAdFailedToLoad: (err) {
          print('Failed to load an interstitial ad: ${err.message}');
        },
      ),
    );
  }

  ...
}
  1. 이 Codelab에서는 사용자가 5단계를 완료한 후 전면 광고가 표시됩니다. 불필요한 광고 요청을 최소화하려면 사용자가 3단계에 도달할 때 광고를 요청하세요.

onNewLevel() 메서드에 다음 행을 추가합니다.

lib/game_route.dart

@override
void onNewLevel(int level, Drawing drawing, String clue) {
  ...

  // TODO: Load an Interstitial Ad
  if (level >= 3 && _interstitialAd == null) {
    _loadInterstitialAd();
  }
}
  1. 게임이 완료되면 게임 점수 대화상자가 표시됩니다. 사용자가 대화상자를 닫으면 사용자를 Awesome Drawing Quiz의 홈 화면으로 보냅니다.

전면 광고는 화면 전환 간에 표시되어야 하므로 사용자가 닫기 버튼을 클릭하면 전면 광고가 표시됩니다.

다음과 같이 onGameOver() 메서드를 수정합니다.

lib/game_route.dart

@override
void onGameOver(int correctAnswers) {
  showDialog(
    context: _scaffoldKey.currentContext,
    builder: (context) {
      return AlertDialog(
        title: Text('Game over!'),
        content: Text('Score: $correctAnswers/5'),
        actions: [
          FlatButton(
            child: Text('close'.toUpperCase()),
            onPressed: () {

              // TODO: Display an Interstitial Ad
              if (_interstitialAd != null) {
                _interstitialAd?.show();
              } else {
                _moveToHome();
              }
            },
          ),
        ],
      );
    },
  );
}
  1. dispose() 콜백 메서드에서 InterstitialAd.dispose() 메서드를 호출하여 InterstitialAd 객체와 연결된 리소스를 릴리스합니다.

lib/game_route.dart

@override
void dispose() {
  ...

  // TODO: Dispose an InterstitialAd object
  _interstitialAd?.dispose();

  ...

  super.dispose();
}

준비가 끝났습니다. 프로젝트를 실행하고 게임을 완료합니다. 전면 광고가 로드된 경우 점수 대화상자에서 닫기 버튼을 클릭하면 전면 광고가 표시됩니다.

c546e438c405e941.gif

9. 보상형 광고 추가

이 섹션에서는 사용자에게 추가 힌트를 리워드로 제공하는 보상형 광고를 추가합니다.

  1. lib/game_route.dart 파일을 엽니다.
  2. _GameRouteState 클래스에서 보상형 광고를 위해 구성원을 추가하고 _loadRewardedAd() 메서드를 구현합니다. 이 메서드는 광고를 최대한 빨리 캐시하기 위해 광고가 닫힐 때(onAdDismissedFullScreenContent) 다른 보상형 광고를 로드합니다.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _rewardedAd
  RewardedAd? _rewardedAd;

  // TODO: Implement _loadRewardedAd()
  void _loadRewardedAd() {
    RewardedAd.load(
      adUnitId: AdHelper.rewardedAdUnitId,
      request: AdRequest(),
      rewardedAdLoadCallback: RewardedAdLoadCallback(
        onAdLoaded: (ad) {
          ad.fullScreenContentCallback = FullScreenContentCallback(
            onAdDismissedFullScreenContent: (ad) {
              setState(() {
                ad.dispose();
                _rewardedAd = null;
              });
              _loadRewardedAd();
            },
          );

          setState(() {
            _rewardedAd = ad;
          });
        },
        onAdFailedToLoad: (err) {
          print('Failed to load a rewarded ad: ${err.message}');
        },
      ),
    );
  }

  ...
}
  1. 게임이 시작할 때 보상형 광고를 요청하려면 initState() 메서드에서 _loadRewardedAd()를 호출합니다.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  @override
  void initState() {
    ...

    // COMPLETE: Load a Rewarded Ad
    _loadRewardedAd();
  }

  ...
}
  1. 사용자가 플로팅 작업 버튼을 클릭하여 보상형 광고를 볼 수 있도록 허용합니다. 버튼은 사용자가 현재 레벨에서 힌트를 사용하지 않았으며 보상형 광고가 로드된 경우에만 표시됩니다.

플로팅 작업 버튼을 표시하려면 _buildFloatingActionButton() 메서드를 다음과 같이 수정합니다. null을 반환하면 화면에서 버튼이 숨겨집니다.

onUserEarnedReward가 보상형 광고에서 가장 중요한 광고 이벤트입니다. 이 이벤트는 사용자가 리워드를 받을 수 있게 될 때(예를 들어 동영상 시청을 완료할 때) 트리거됩니다.

이 Codelab에서 QuizManager.instance.useHint() 메서드는 콜백에서 호출되어 힌트 문자열에서 1자를 더 표시합니다. 앱에서는 onAdClosed 콜백의 보상형 광고를 새로고침하여 최대한 빨리 광고가 준비될 수 있도록 합니다.

lib/game_route.dart

Widget? _buildFloatingActionButton() {
  // TODO: Return a FloatingActionButton if a rewarded ad is available
  return (!QuizManager.instance.isHintUsed && _rewardedAd != null)
      ? FloatingActionButton.extended(
          onPressed: () {
            showDialog(
              context: context,
              builder: (context) {
                return AlertDialog(
                  title: Text('Need a hint?'),
                  content: Text('Watch an Ad to get a hint!'),
                  actions: [
                    TextButton(
                      child: Text('cancel'.toUpperCase()),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                    TextButton(
                      child: Text('ok'.toUpperCase()),
                      onPressed: () {
                        Navigator.pop(context);
                        _rewardedAd?.show(
                          onUserEarnedReward: (_, reward) {
                            QuizManager.instance.useHint();
                          },
                        );
                      },
                    ),
                  ],
                );
              },
            );
          },
          label: Text('Hint'),
          icon: Icon(Icons.card_giftcard),
        )
      : null;
}
  1. dispose() 콜백 메서드에서 RewardedAd.dispose() 메서드를 호출하여 RewardedAd 객체와 연결된 리소스를 릴리스합니다.

lib/game_route.dart

@override
void dispose() {
  ...

  // TODO: Dispose a RewardedAd object
  _rewardedAd?.dispose();

  ...

  super.dispose();
}

준비가 끝났습니다. 프로젝트를 실행하고 게임을 플레이합니다. 보상형 광고가 로드되면 화면 하단에 힌트 버튼이 표시됩니다. 추가 힌트를 얻으려면 힌트 버튼을 클릭하세요.

4a114d243ae3e71d.gif

10. 모두 완료했습니다.

Codelab을 완료했습니다. 이 Codelab의 완료된 코드는 android_studio_folder.pngcomplete 폴더에서 확인할 수 있습니다.

배너 광고와 네이티브 인라인 광고를 구현하는 방법을 알아보려면 Flutter 앱에 AdMob 배너 광고 및 네이티브 인라인 광고 추가 Codelab을 확인하세요.

자세한 내용은 다른 Flutter Codelab을 참고하세요.