PromleeBlog
sitemap
aboutMe

posting thumbnail
Flutter에서 보상형 전면 광고 적용 및 이벤트 리슨 방법
How to Implement Rewarded Interstitial Ads in Flutter

📅

들어가기 전에 🔗

앱을 개발하다 보면 사용자에게 자연스럽게 광고를 보여주면서도,
사용자 경험
을 해치지 않는 방법을 고민하게 됩니다. 특히 보상형 광고는 사용자가 자발적으로 참여하고, 그에 대한 보상을 제공할 수 있어서 매우 유용한 형태죠.
이번 글에서는 Google AdMob의
보상형 전면 광고(Rewarded Interstitial Ad)
를 Flutter 앱에 적용하는 방법을 소개합니다. 특히 버튼을 눌렀을 때 광고를 띄우고, 사용자의 광고 시청 여부에 따라 로직을 처리하는 방법까지 자세히 설명드리겠습니다.

AdMob 설정 및 기본 설치 🔗

먼저 Google AdMob에서 광고 ID를 발급받고 Flutter 프로젝트에 필요한 패키지를 설치하는 과정부터 시작하겠습니다.
  1. Google AdMob↗에 접속하여 앱을 등록합니다.
  2. 광고 단위 ID를 생성합니다. 이번 예제에서는
    보상형 전면 광고
    유형을 선택합니다.
  3. Flutter 프로젝트에 google_mobile_ads 패키지를 추가합니다.
flutter pub add google_mobile_ads
  1. Android와 iOS에 필요한 설정을 추가합니다.
    • Android의 경우 AndroidManifest.xml에 다음과 같은 권한과 메타데이터를 추가해야 합니다.
<!-- AndroidManifest.xml -->
<manifest>
  <application>
    <meta-data
      android:name="com.google.android.gms.ads.APPLICATION_ID"
      android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
  </application>
</manifest>
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy</string>
  1. 앱 시작 시 AdMob SDK를 초기화합니다.
main.dart
import 'dart:developer';
 
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
 
class RewardedInterstitialAdExample extends StatefulWidget {
  const RewardedInterstitialAdExample({super.key});
 
  @override
  RewardedInterstitialAdExampleState createState() =>
      RewardedInterstitialAdExampleState();
}
 
class RewardedInterstitialAdExampleState
    extends State<RewardedInterstitialAdExample> {
  RewardedInterstitialAd? _rewardedInterstitialAd;
  bool _isAdLoaded = false;
  void _loadAd() {
    RewardedInterstitialAd.load(
      adUnitId: 'ca-app-pub-3940256099942544/5354046379', // 테스트 ID
      request: const AdRequest(),
      rewardedInterstitialAdLoadCallback: RewardedInterstitialAdLoadCallback(
        onAdLoaded: (ad) {
          log('onAdLoaded: 광고 로드 완료');
          setState(() {
            _rewardedInterstitialAd = ad;
            _isAdLoaded = true;
          });
        },
        onAdFailedToLoad: (error) {
          log('onAdFailedToLoad: 광고 로드 실패: $error');
        },
      ),
    );
  }
 
  void _showAd() {
    if (_isAdLoaded && _rewardedInterstitialAd != null) {
      _rewardedInterstitialAd!.fullScreenContentCallback =
          FullScreenContentCallback(
        onAdDismissedFullScreenContent: (ad) {
          log('onAdDismissedFullScreenContent: 광고가 닫혔습니다.');
          ad.dispose();
        },
        onAdFailedToShowFullScreenContent: (ad, error) {
          log('onAdFailedToShowFullScreenContent: 광고 표시 실패: $error');
        },
      );
      _rewardedInterstitialAd!.show(onUserEarnedReward: (ad, reward) {
        log('onUserEarnedReward: 사용자가 보상을 획득했습니다: ${reward.amount} ${reward.type}');
        // 보상 로직 처리
      });
      _rewardedInterstitialAd = null;
      _isAdLoaded = false;
    } else {
      log('onAdFailedToShowFullScreenContent: 광고가 아직 준비되지 않았습니다.');
    }
  }
 
  @override
  void initState() {
    super.initState();
    _loadAd();
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('보상형 전면 광고 예제')),
      body: Center(
        child: ElevatedButton(
          onPressed: _showAd,
          child: const Text('광고 보기'),
        ),
      ),
    );
  }
}
위 예제에서는 광고가 준비되면 버튼을 통해 광고를 보여주고, 사용자가 광고를 끝까지 시청하면
보상 이벤트(onUserEarnedReward)
가 발생하여 보상 처리를 할 수 있습니다.
테스트 광고 표시
테스트 광고 표시

광고 이벤트 리슨 및 상태 관리 🔗

광고의 상태를 잘 관리하면 사용자 경험을 더 부드럽게 만들 수 있습니다. 예를 들어 광고가 끝나면 다시 광고를 로드하고, 광고가 없을 경우 버튼을 비활성화하는 방식도 가능합니다.
예시처럼 _isAdLoaded 상태를 이용해 버튼 활성화를 제어할 수 있습니다. 또한 광고 실패나 닫힘 이벤트를 리슨해서 앱 흐름을 자연스럽게 유지해야 합니다.
광고 생명주기 관리
는 다음과 같은 콜백을 통해 구현합니다:
정상 작동 시 로그
정상 작동 시 로그
광고 차단 프로그램(adguard) 동작 시 로그
광고 차단 프로그램(adguard) 동작 시 로그
onAdFailedToLoad: 광고 로드 실패: LoadAdError(code: 0, domain: com.google.android.gms.ads, message: Error while connecting to ad server: Unable to resolve host "googleads.g.doubleclick.net": No address associated with hostname, responseInfo: ResponseInfo(responseId: null, mediationAdapterClassName: , adapterResponses: [], loadedAdapterResponseInfo: null), responseExtras: {})
이러한 이벤트를 적절히 리슨하여 광고의 흐름을 설계하면 서버 로그 저장 등 다양한 기능을 구현할 수 있습니다.

결론 🔗

보상형 전면 광고는 사용자에게 자연스럽게 참여를 유도하고 앱 수익을 창출할 수 있는 좋은 방법입니다. Flutter에서는 google_mobile_ads 패키지를 통해 쉽게 적용할 수 있으며, 적절한 이벤트 리슨과 상태 관리를 통해 광고 흐름을 부드럽게 구성할 수 있습니다.
이번 글에서는 AdMob 설정부터 Flutter 코드 작성, 이벤트 리슨까지 전반적인 흐름을 살펴보았습니다. 직접 테스트 광고로 연습해보신 후, 실제 광고 ID로 교체해 사용하시면 되겠습니다.

참고 🔗