Flutter 앱에 AdMob 광고 추가

빌드할 항목

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

이 Codelab을 진행하는 동안 코드 버그, 문법 오류, 불명확한 문구 등의 문제가 발생하면 Codelab 왼쪽 하단에 있는 오류 신고 링크를 클릭하여 문제를 신고해 주세요.

학습할 내용

  • Flutter 앱용 Firebase 프로젝트 설정 방법
  • Firebase AdMob 플러그인 구성 방법
  • Flutter 앱에서 배너, 전면 광고, 보상형 광고를 사용하는 방법

필요한 항목

  • Android 스튜디오 3.6 이상
  • Xcode(iOS 지원용)

AdMob 사용 경험 수준을 평가해 주세요.

초급 중급 고급

이 Codelab에서 학습하고 싶은 내용은 무엇인가요?

주제를 처음 접하기 때문에 간단하게 내용을 파악하고 싶습니다. 이 주제에 관해 약간 알고 있지만 한 번 더 확인하고 싶습니다. 프로젝트에 사용할 코드 예를 찾고 있습니다. 특정 항목에 대한 자세한 설명을 찾고 있습니다.

Flutter 개발 환경 설정

  1. flutter.dev의 설치 안내에 따라 컴퓨터에 Flutter SDK를 설치합니다.
  2. Android 스튜디오를 열고 구성 페이지의 단계에 따라 Android 스튜디오용 Flutter와 Dart 플러그인을 설치합니다.

코드 다운로드

이 Codelab의 모든 코드를 ZIP 파일로 다운로드하려면 다음 버튼을 클릭하세요.

소스 코드 다운로드

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이 완료된 코드입니다.

시작 프로젝트 가져오기

  1. Android 스튜디오를 엽니다.
  2. 시작 화면에서 Open an existing Android Studio project를 선택합니다. a3a1fa1afc967e37.png
  3. 이전 단계에서 다운로드한 코드에서 android_studio_folder.pngstarter 폴더를 엽니다.

a879fa2385ba368f.png

  1. Dart Analysis 탭에 다음과 같은 오류 메시지가 표시될 수 있습니다. 이 오류는 샘플 프로젝트에서 사용하는 패키지가 아직 다운로드되지 않았으므로 기존 프로젝트를 Android 스튜디오로 가져왔을 때 한 번만 발생합니다.

2b8fbccf84e1e8a5.png

  1. 오류를 수정하려면 편집기 창 상단에서 Get dependencies를 클릭합니다. 그러면 샘플 프로젝트가 종속된 패키지가 다운로드됩니다.

dc017166e44ac333.png

  1. 다운로드가 완료되면 Dart Analysis 탭에 오류가 표시되지 않습니다. 이제 프로젝트를 개발할 준비가 되었습니다.

Firebase AdMob 플러그인을 사용하여 AdMob 광고를 게재하려면 Firebase 프로젝트를 설정해야 합니다.

Firebase 프로젝트 만들기

  1. Firebase Console에서 프로젝트 추가를 클릭합니다.
  2. 프로젝트 이름으로 Awesome Drawing Quiz를 입력합니다.
  3. 프로젝트에 Google 애널리틱스를 사용 설정하고 계속을 클릭합니다.

87590d75b00db648.png

  1. 프로젝트에 적용할 애널리틱스의 위치 및 설정을 선택합니다. 약관을 읽고 동의한 다음 프로젝트 만들기를 클릭합니다.

700c64d82fedbd0b.png

  1. 약 1분 후에 Firebase 프로젝트가 준비됩니다.

Firebase에 앱 등록

Firebase Console에서 이전 단계에서 만든 Awesome Drawing Quiz 프로젝트를 선택합니다.

Android 앱 등록

  1. 프로젝트 개요 페이지 중앙에 있는 Android 아이콘을 클릭하여 설정 워크플로를 시작합니다.
  2. Android 패키지 이름 필드에 com.codelab.awesomedrawingquiz를 입력합니다.
  3. 앱 닉네임 필드에 Awesome Drawing Quiz (Android)를 입력합니다.
  4. 앱 등록을 클릭합니다.
  5. 이후 사용할 google-services.json 파일을 다운로드합니다.

iOS 앱 등록

  1. 프로젝트 개요 페이지 중앙에 있는 iOS 아이콘 또는 앱 추가(+) 아이콘을 클릭하여 설정 워크플로를 시작합니다.
  2. iOS 번들 ID 필드에 com.codelab.awesomedrawingquiz를 입력합니다.
  3. 앱 닉네임 필드에 Awesome Drawing Quiz (iOS)를 입력합니다.
  4. 앱 등록을 클릭합니다.
  5. 이후 사용할 GoogleService-Info.plist 파일을 다운로드합니다.

Firebase 구성 파일 추가

다음 안내에서는 Android와 iOS에 Firebase를 구성하는 방법을 설명합니다.

Android용 구성

  1. 이 Codelab의 개발 환경 설정 단계에서 시작 프로젝트 가져오기 섹션을 참고하여 Android 스튜디오에서 시작 프로젝트를 엽니다.
  2. google-services.json 파일을 Awesome Drawing Quiz Flutter 프로젝트의 android/app 디렉터리로 이동합니다.

bd0729c424b0c79d.png

  1. 루트 수준(프로젝트 수준)의 Gradle 파일(android/build.gradle)에서 Google 서비스 Gradle 플러그인을 포함하도록 규칙을 추가합니다. Google Maven 저장소가 있는지 확인합니다.

android/build.gradle

buildscript {

    repositories {
      // Check that you have the following line (if not, add it):
      google()  // Google's Maven repository
    }

    ...

    dependencies {
      ...

      // TODO: Add Google Services plugin
      classpath 'com.google.gms:google-services:4.3.3'
    }
}

allprojects {
    ...

    repositories {
      // Check that you have the following line (if not, add it):
      google()  // Google's Maven repository
      ...
    }
}
  1. 모듈(앱 수준) Gradle 파일(android/app/build.gradle)에서 Google 서비스 Gradle 플러그인을 적용합니다.

android/app/build.gradle

...

// TODO: Apply google-services plugin
apply plugin: 'com.google.gms.google-services'

android {
  ...
}

...

iOS용 구성

  1. 이 Codelab의 개발 환경 설정 단계에서 시작 프로젝트 가져오기 섹션을 참고하여 Android 스튜디오에서 시작 프로젝트를 엽니다.
  2. ios 디렉터리에서 파일을 엽니다. (예: ios/Runner/AppDelegate.swift)
  3. Open iOS module in Xcode를 클릭합니다.

b0e50d31ada7bf46.png

  1. Xcode에서 GoogleService-Info.plist 파일을 Runner 디렉터리로 드래그하여 구성 파일을 Xcode 프로젝트로 가져옵니다.

1f552ff12b67008.png

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

시작하기 전에 다음의 AdMob 용어에 익숙해지는 것이 좋습니다.

광고 단위

광고 단위는 AdMob 광고 코드 하나의 결과로 표시되는 광고 조합입니다. AdMob 계정에서 광고 단위를 만들고 맞춤설정할 수 있습니다.

각 광고 단위에는 광고 단위 ID라는 고유한 식별자가 있습니다. 앱에서 새 광고 단위를 구현할 때 요청 시 광고 단위 ID를 참조하여 광고 네트워크에 광고 전송 위치를 알려야 합니다.

배너 광고

배너 광고는 앱의 레이아웃 내부(즉, 기기 화면의 상단이나 하단)에 게재됩니다. 사용자가 앱과 상호작용하는 동안 화면에 머무르며 일정 시간이 지나면 자동으로 새로고침할 수 있습니다.

전면 광고

전면 광고는 호스트 앱의 인터페이스를 가리는 전체 화면 광고입니다. 일반적으로 앱 흐름상 자연스러운 전환 시점(예: 활동이 바뀌는 시점 또는 게임에서 다음 레벨로 넘어가면서 잠시 중단될 때)에 광고가 게재됩니다.

보상형 광고

보상형 광고는 상호작용하는 사용자에게 인앱 리워드를 제공하는 광고입니다.

Android용 설정

이 섹션에서는 AdMob에 Android 앱 및 광고 단위를 추가하는 방법을 설명합니다.

Android 앱 추가

AdMob에 Android 앱을 추가하려면 다음 안내를 따르세요.

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

152e1694fd0ce870.png

  1. 이 Codelab을 완료하기 위해 사용자 측정항목을 사용 설정할 필요는 없습니다. 하지만 사용자 측정항목을 사용 설정하면 자세한 사용자 행동이 포함된 애널리틱스 데이터가 제공되므로 이를 사용하는 것이 좋습니다. 추가를 클릭하여 절차를 완료합니다.

5204925f5c652b41.png

  1. 새 앱 ID를 기록해 둡니다(ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy). 광고를 실행하려면 샘플 프로젝트의 소스 코드에 이 ID를 추가해야 합니다.

광고 단위 만들기

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

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

광고 단위 메뉴에서 안내에 따라 배너, 전면 광고, 보상형 광고 단위를 만듭니다.

배너

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

전면 광고

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

보상형 광고

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

iOS용 설정

이 섹션에서는 AdMob에 iOS 앱 및 광고 단위를 추가하는 방법을 설명합니다.

iOS 앱 추가

AdMob에 iOS 앱을 추가하려면 다음 안내를 따르세요.

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

a8fa48af652021d8.png

  1. 이 Codelab을 완료하기 위해 사용자 측정항목을 사용 설정할 필요는 없습니다. 하지만 사용자 측정항목을 사용 설정하면 자세한 사용자 행동이 포함된 애널리틱스 데이터가 제공되므로 이를 사용하는 것이 좋습니다. 추가를 클릭하여 절차를 완료합니다.

5204925f5c652b41.png

  1. 새 앱 ID를 기록해 둡니다(ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy). 광고를 실행하려면 샘플 프로젝트의 소스 코드에 이 ID를 추가해야 합니다.

광고 단위 만들기

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

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

광고 단위 메뉴에서 안내에 따라 배너, 전면 광고, 보상형 광고 단위를 만듭니다.

배너

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

전면 광고

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

보상형 광고

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

사전 구성된 AdMob 앱 및 광고 단위 사용(선택사항)

새 애플리케이션 및 광고 단위를 직접 만드는 대신 Codelab을 따르려면 이 Codelab용으로 준비된 AdMob 앱 ID와 광고 단위 ID를 사용하면 됩니다.

Android

Android용 테스트 AdMob ID는 다음과 같습니다.

항목

앱 ID/광고 단위 ID

AdMob 앱 ID

ca-app-pub-3940256099942544~4354546703

배너

ca-app-pub-3940256099942544/8865242552

전면 광고

ca-app-pub-3940256099942544/7049598008

보상형

ca-app-pub-3940256099942544/8673189370

iOS

iOS용 테스트 AdMob ID는 다음과 같습니다.

항목

앱 ID/광고 단위 ID

AdMob 앱 ID

ca-app-pub-3940256099942544~2594085930

배너

ca-app-pub-3940256099942544/4339318960

전면 광고

ca-app-pub-3940256099942544/3964253750

보상형

ca-app-pub-3940256099942544/7552160883

Flutter는 플러그인을 사용하여 다양한 플랫폼별 서비스에 액세스할 권한을 제공합니다. 플러그인에는 각 플랫폼의 서비스 및 API에 액세스하기 위한 플랫폼별 코드가 포함되어 있습니다.

firebase_admob 플러그인은 AdMob API를 사용하여 배너, 전면 광고, 보상형 광고를 로드하고 표시하도록 지원합니다.

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

Firebase AdMob 플러그인을 종속 항목으로 추가

Awesome Drawing Quiz 프로젝트에서 AdMob API에 액세스하려면 firebase_admob 플러그인을 프로젝트의 루트에 위치한 pubspec.yaml 파일에 종속 항목으로 추가합니다.

pubspec.yaml

...

dependencies:
  flutter:
    sdk: flutter
  google_fonts: ^0.3.9

  # Add the following line
  firebase_admob: ^0.9.3

...

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

d9fc62bf4054cea9.png

AndroidManifest.xml 업데이트(Android)

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

android/app/src/main/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 앱 ID의 문자열 값과 함께 GADApplicationIdentifier 키를 추가합니다. 예를 들어, AdMob 앱 ID가 ca-app-pub-3940256099942544~1458002511이면 Info.plist 파일에 다음 줄을 추가해야 합니다.

ios/Runner/Info.plist

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

lib 디렉터리에 ad_manager.dart라는 새 파일을 만듭니다. 그런 다음, Android와 iOS용 AdMob 앱 ID와 광고 단위 ID를 제공하는 AdManager 클래스를 구현합니다.

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

lib/ad_manager.dart

import 'dart:io';

class AdManager {

  static String get appId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_ADMOB_APP_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_ADMOB_APP_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  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 new 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 new 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 new UnsupportedError("Unsupported platform");
    }
  }
}

이 Codelab에 맞게 사전 구성된 AdMob 앱 ID와 광고 단위 ID를 사용하려면 다음 코드 스니펫을 사용하세요.

lib/ad_manager.dart

import 'dart:io';

class AdManager {

  static String get appId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544~4354546703";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544~2594085930";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

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

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

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

광고를 로드하기 전에 AdMob SDK를 초기화해야 합니다. lib/home_route.dart 파일을 열고 _initAdMob()을 수정하여 게임을 시작하기 전에 SDK를 초기화합니다.

lib/home_route.dart

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

import 'package:awesome_drawing_quiz/app_theme.dart';

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

import 'package:flutter/material.dart';

...

class _HomeRouteState extends State<HomeRoute> {

  ...

  Future<void> _initAdMob() {
    // TODO: Initialize AdMob SDK
    return FirebaseAdMob.instance.initialize(appId: AdManager.appId);
  }
}

이 섹션에서는 다음과 같이 게임 화면 상단에 배너 광고를 추가합니다.

580a296a77065928.png 6d6659121dbf382e.png

lib/game_route.dart 파일을 열고 다음 줄을 추가하여 ad_manager.dartfirebase_admob.dart를 가져옵니다.

lib/game_route.dart

...

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

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

class GameRoute extends StatefulWidget {
  ...
}

그런 다음, _GameRouteState 클래스에서 배너 광고용으로 다음 멤버 및 메서드를 추가합니다.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _bannerAd
  BannerAd _bannerAd;

  ...

  // TODO: Implement _loadBannerAd()
  void _loadBannerAd() {
    _bannerAd
      ..load()
      ..show(anchorType: AnchorType.top);
  }

  ...
}

initState() 메서드에서 BannerAd 객체를 만들고 배너 광고를 로드합니다. 배너 광고는 320x50 배너(AdSize.banner)로 표시됩니다.

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Initialize _bannerAd
  _bannerAd = BannerAd(
      adUnitId: AdManager.bannerAdUnitId,
      size: AdSize.banner,
  );

  // TODO: Load a Banner Ad
  _loadBannerAd();
}

마지막으로, dispose() 콜백 메서드에서 BannerAd.dispose() 메서드를 호출하여 BannerAd 객체와 연결된 리소스를 해제합니다.

lib/game_route.dart

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

  ...

  super.dispose();
}

이제 완료되었습니다. 프로젝트를 실행하여 게임 화면 상단에 있는 배너 광고를 확인합니다.

d82f07411be93d37.png f221e4821191cf99.png

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

먼저, _GameRouteState 클래스에 다음 멤버와 메서드를 전면 광고용으로 추가합니다.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _interstitialAd
  InterstitialAd _interstitialAd;

  // TODO: Add _isInterstitialAdReady
  bool _isInterstitialAdReady;

  ...

  // TODO: Implement _loadInterstitialAd()
  void _loadInterstitialAd() {
    _interstitialAd.load();
  }

  // TODO: Implement _onInterstitialAdEvent()
  void _onInterstitialAdEvent(MobileAdEvent event) {
    switch (event) {
      case MobileAdEvent.loaded:
        _isInterstitialAdReady = true;
        break;
      case MobileAdEvent.failedToLoad:
        _isInterstitialAdReady = false;
        print('Failed to load an interstitial ad');
        break;
      case MobileAdEvent.closed:
        _moveToHome();
        break;
      default:
      // do nothing
    }
  }

  ...
}

그런 다음, initState() 메서드에서 _isInterstitialAdReady_interstitialAd를 초기화합니다. _onInterstitialAdEvent_interstitialAd의 광고 이벤트 리스너로 구성되어 있으므로 _interstitialAd의 모든 광고 이벤트는 _onInterstitialAdEvent 메서드에 전달됩니다.

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Initialize _isInterstitialAdReady
  _isInterstitialAdReady = false;

  // TODO: Initialize _interstitialAd
  _interstitialAd = InterstitialAd(
    adUnitId: AdManager.interstitialAdUnitId,
    listener: _onInterstitialAdEvent,
  );
}

이 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 && !_isInterstitialAdReady) {
    _loadInterstitialAd();
  }
}

게임이 완료되면 게임 점수 대화상자가 표시됩니다. 사용자가 대화상자를 닫으면 Awesome Drawing Quiz 홈 화면으로 사용자를 라우팅합니다.

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

다음과 같이 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: <Widget>[
          FlatButton(
            child: Text('close'.toUpperCase()),
            onPressed: () {

              // TODO: Display an Interstitial Ad
              if (_isInterstitialAdReady) {
                _interstitialAd.show();
              }

              _moveToHome();
            },
          ),
        ],
      );
    },
  );
}

마지막으로, dispose() 콜백 메서드에서 InterstitialAd.dispose() 메서드를 호출하여 InterstitialAd 객체와 연결된 리소스를 해제합니다.

lib/game_route.dart

@override
void dispose() {
  ...

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

  ...

  super.dispose();
}

이제 완료되었습니다. 프로젝트를 실행하여 게임이 완료된 후 표시되는 전면 광고를 확인합니다.

53f44b98e8a0c446.gif

이 섹션에서는 보상으로 추가 힌트를 제공하는 보상형 광고를 추가합니다.

먼저 _GameRouteState 클래스에 보상형 광고의 멤버와 메서드를 추가합니다. RewardedVideoAd는 싱글톤 객체이므로 RewardedVideoAd 클래스의 인스턴스를 관리할 멤버가 필요하지 않습니다.

RewardedVideoAdEvent.rewarded는 보상형 광고에서 가장 중요한 광고 이벤트입니다. 이 이벤트는 사용자가 보상을 받을 자격이 되면 트리거됩니다(예: 동영상 시청 완료). 이 Codelab에서 RewardedVideoAdEvent.rewarded는 힌트 문자열에 문자를 하나 더 표시하는 QuizManager.instance.useHint() 메서드를 호출합니다.

또한 광고 이벤트에 따라 RewardedVideoAdEvent.rewarded_isRewardedAdReady의 값을 변경하여 UI를 업데이트합니다. _isRewardedAdReady는 사용자가 광고를 닫을 때 광고를 새로고침하여 광고가 최대한 빨리 준비되도록 합니다.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _isRewardedAdReady
  bool _isRewardedAdReady;

  ...

  // TODO: Implement _loadRewardedAd()
  void _loadRewardedAd() {
    RewardedVideoAd.instance.load(
      targetingInfo: MobileAdTargetingInfo(),
      adUnitId: AdManager.rewardedAdUnitId,
    );
  }

  // TODO: Implement _onRewardedAdEvent()
  void _onRewardedAdEvent(RewardedVideoAdEvent event,
      {String rewardType, int rewardAmount}) {
    switch (event) {
      case RewardedVideoAdEvent.loaded:
        setState(() {
          _isRewardedAdReady = true;
        });
        break;
      case RewardedVideoAdEvent.closed:
        setState(() {
          _isRewardedAdReady = false;
        });
        _loadRewardedAd();
        break;
      case RewardedVideoAdEvent.failedToLoad:
        setState(() {
          _isRewardedAdReady = false;
        });
        print('Failed to load a rewarded ad');
        break;
      case RewardedVideoAdEvent.rewarded:
        QuizManager.instance.useHint();
        break;
      default:
      // do nothing
    }
  }

  ...
}

다음으로, _isRewardedAdReady를 초기화하고 _onRewardedAdEvent를 광고 이벤트 리스너로 설정합니다. 그런 다음, _loadRewardedAd()를 호출하여 보상형 광고를 요청합니다.

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Initialize _isRewardedAdReady
  _isRewardedAdReady = false;

  // TODO: Set Rewarded Ad event listener
  RewardedVideoAd.instance.listener = _onRewardedAdEvent;

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

다음으로, 사용자가 플로팅 작업 버튼을 클릭하여 보상형 광고를 시청하도록 허용합니다. 사용자가 현재 레벨에서 힌트를 사용하지 않은 상태이고 보상형 광고가 로드되어 있는 경우에만 버튼이 표시됩니다.

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

lib/game_route.dart

Widget _buildFloatingActionButton() {
  // TODO: Return a FloatingActionButton if a Rewarded Ad is available
  return (!QuizManager.instance.isHintUsed && _isRewardedAdReady)
      ? 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: <Widget>[
                    FlatButton(
                      child: Text('cancel'.toUpperCase()),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                    FlatButton(
                      child: Text('ok'.toUpperCase()),
                      onPressed: () {
                        Navigator.pop(context);
                        RewardedVideoAd.instance.show();
                      },
                    ),
                  ],
                );
              },
            );
          },
          label: Text('Hint'),
          icon: Icon(Icons.card_giftcard),
        )
      : null;
}

마지막으로, dispose() 콜백 메서드에서 보상형 광고 이벤트 리스너를 삭제합니다.

lib/game_route.dart

@override
void dispose() {
  ...

  // TODO: Remove Rewarded Ad event listener
  RewardedVideoAd.instance.listener = null;

  ...

  super.dispose();
}

이제 완료되었습니다. 프로젝트를 실행하고 보상형 광고를 시청하여 추가 힌트를 얻습니다.

2a79a3db6b44dae9.gif

9db81af632cb2b15.png특별한 성과를 이루었습니다.

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

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