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.dartgoogle_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을 참고하세요.