본문 바로가기

[Flutter, admob] 앱 오프닝 광고(App open ads) 플러터 앱에 추가하기(사용법) -ChatGPT와 공식 문서로 코딩 공부

ironwhale 2023. 10. 26.

부업으로 안드로이드 앱을 혼자 개발하고 있는 저의 앱의 주 수입원은 애드몹 광고입니다. 그동안은 배너 광고, 네이티브 광고(배너모양) 외엔 없었습니다. 그러던 와중 다른 1인 개발과 부업 개발자 커뮤니티에서 전면광고에 대한 이야기를 접하였고 이번 기회에 앱이 시작될 때 광고가 나오도록 하는 전면광고 게제를 해보기로 하면서 플러터 앱에 앱 오프닝 광고의 사용법에 대해 정리해보았습니다. 

 

이번에 이것을 공부하면서 저는 모르는 부분이 나올때마다 구글링이 아닌 ChatGPT를 활용했는데 처음에는 자바보다 사용자가 적은 플러터에 대한 질문이었지만 ChatGPT 엄청 잘 알려주어 수월하게 공부할 수 있었습니다.  

 

아래 나온 내용들은 공식 문서와 chatGPT와 함께 공부한 자료입니다. 
 

앱 오프닝 광고(App open Ads) 

앱오프닝광고 app open ads
앱 오프닝??

구글 공식 개발자 사이트에 admob을 가서 전면 광고 게재 방법을 찾던 중 앱이 켜질때 광고가 나오는 앱 오프닝 광고를 발견하였습니다. 지금 저에게 딱 맞는 광고라고 생각되어 이번에 배운 앱 오프닝 광고를 소개 해보고자 합니다. 


앱 오프닝 광고(App open ads) 구현 과정

1. 광고 게재 상태를 관리하는 매니져 클래스 생성
2. 앱이 백그라운드 상태인지 foreground 상태인지 감지하는 클래스 생성
3. main.dart에 광고 게제 코드 구현


1.  광고 게재 상태를 관리하는 매니져 클래스 생성

앱 오프닝 광고(app open ads)를 앱에서 보이게 하기 위해서는 광고를 로드하여 AppOpenAd 인스턴스인 _appOpenAd를 만들고 _appOpenAd!.show()을 실행 시켜야합니다. 

 

그래서 광고를 로드하는 loadAd() 메소를 만들고 _appOpenAd!.show()를 실행시키는 showAdIfAvailable()  만들어야합니다. 

광고 로드하기

앱 오프닝 광고를 로드 하기위해서는 AppOpenAd.load()를 사용해야 합니다. 여기서 광고의 방향을 지정하는 orientation과 광고가 로드되었을때 실행되는 함수, 실패했을 때 실되는 함수를 입력할 수 있습니다. 

 

광고 송출, 광고 상태에 따른 콜백 처리

위에서 로드된 앱 오프닝 광고(app open ads)를 게재하는 showAdIfAvailable() 메소드에는 여러가지 조건이 있습니다. 

 

1. _appOpenAd가  null 일때  loadAd() 메소드를 실행해 광고를 로드하고 그냥 리턴

2. 이미 앱 오프닝 광고가 나오고 있으면 아무런 동작을 하지 않고 리턴

 

위에 두가지 조건을 통과해서 _appOpenAd.show()를 통해 앱에 오프닝 광고를 나오게 할 수 있습니다. 

 

그전에 _appOpenAd!.fullScreenContentCallback에 앱 오프닝 광고에 따라 필요한 로직을 수행할 수 있습니다. 아래의 1~3까지는 ChatGPT에 물어보고 답변해준 내용입니다. 

일반적으로 _appOpenAd!.fullScreenContentCallback에는 다음과 같은 이벤트 처리자 콜백이 설정됩니다:
1. onAdShowedFullScreenContent: 광고가 전체 화면으로 표시될 때 호출되며, 이 시점에서 광고가 화면에 표시됩니다.

2. onAdFailedToShowFullScreenContent: 광고 표시에 실패했을 때 호출되며, 오류 상황을 처리할 수 있습니다.

3. onAdDismissedFullScreenContent: 사용자가 광고를 닫거나 광고가 종료되면 호출되며, 이 시점에서 광고를 정리하고, 필요한 경우 다음 광고를 로드합니다.

따라서 이러한 콜백을 사용하여 광고의 표시, 실패, 종료 등의 이벤트를 처리하고 광고를 적절하게 관리할 수 있습니다. 예를 들어, 광고가 종료되면 새로운 광고를 로드하고 광고 경험을 계속 제공할 수 있습니다.

 

전체코드

import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:my_memo_app/common/const/ad_unit_id.dart';
import 'package:my_memo_app/common/util/logger.dart';

import 'dart:io' show Platform;

final appOpenAdManagerProvider = Provider<AppOpenAdManager>((ref) {
  // important!!!!
  String os = Platform.isAndroid ? "android" : "ios";

  final String appOpenId = OPEN_ID[os]!;

  return AppOpenAdManager(adUnitId: appOpenId);
});

class AppOpenAdManager {
  AppOpenAd? _appOpenAd;
  final String adUnitId;

  AppOpenAdManager({required this.adUnitId});

  void loadAd() {
    AppOpenAd.load(
        adUnitId: adUnitId,
        request: const AdRequest(),
        adLoadCallback: AppOpenAdLoadCallback(onAdLoaded: (AppOpenAd ad) {
          _appOpenAd = ad;
        }, onAdFailedToLoad: (LoadAdError error) {
          logger.e(error);
        }),
        orientation: AppOpenAd.orientationPortrait);
  }

  bool get _isAppOpenAdAvailable => _appOpenAd != null;
  bool _isShowingAds = false;

  //
  void showAdIfAvailable() {
    // _appOpenAd null check
    if (!_isAppOpenAdAvailable) {
      loadAd();
      return;
    }

    // 이미 광고가 로드 중이면 아무 것도 안함
    if (_isShowingAds) {
      return;
    }

    _appOpenAd!.fullScreenContentCallback = FullScreenContentCallback(
      onAdShowedFullScreenContent: (ad) {
        _isShowingAds = true;
      },
      onAdFailedToShowFullScreenContent: (ad, error) {
        _appOpenAd = null;
        ad.dispose();
        _isShowingAds = false;
      },
      onAdDismissedFullScreenContent: (ad) {
        _isShowingAds = false;
        _appOpenAd = null;
        ad.dispose();
        loadAd();
      },
    );

    _appOpenAd!.show();
  }
}

 


2. 앱이 백그라운드 상태인지 foreground 상태인지 감지하는 클래스 생성

이제 앱의 상태에 따라 앱 오프닝 광고를 게재하는 _adManager.showAdIfAvailable() 을 실행하는 로직을 만들 차례입니다. 

 

앱의 상태를 파악하기

listenToAppStateChanges() 메소드는 앱의 상태가 background, foreground로 바뀔때 마다 특정 동작을 수행하는 역할을 합니다. 이것을 하기위해 AppStateEventNotifier를 사용합니다. 

 

AppStateEventNotifier.startListening()을 실행시킨 후 상태과 바뀔때마다 아래 코드가 실행됩니다. 

    AppStateEventNotifier.appStateStream.forEach((AppState state) {
      _onAppStateChanged(state);
    });

앱이 foreground일때 광고 게재

_onAppStateChanged(AppState state) 메소드는 현재의 앱이 background인지 foreground인지 앱의 상태를 파라메터로 받아 foreground일때 _adManager.showAdIfAvailable() 실행 시켜 광고를 개제합니다. 

전체코드

import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:my_memo_app/common/admob/app_open_ad_manager.dart';
import 'package:my_memo_app/common/util/logger.dart';

final appLifeCycleReactorProvider = Provider<AppLifeCycleReactor>((ref) {
  final adManager = ref.watch(appOpenAdManagerProvider)..loadAd();
  return AppLifeCycleReactor(adManager);
});

class AppLifeCycleReactor {
  final AppOpenAdManager _adManager;

  AppLifeCycleReactor(this._adManager){
    listenToAppStateChanges();
  }

  void listenToAppStateChanges() {
    AppStateEventNotifier.startListening();
    AppStateEventNotifier.appStateStream.forEach((AppState state) {
      _onAppStateChanged(state);
      logger.d(state);
    });
  }

  void _onAppStateChanged(AppState state) {
    if (state == AppState.foreground) {
      _adManager.showAdIfAvailable();
    }
  }
}

3. main.dart에 광고 게제 코드 구현

이제 앞서 만든 AppLifeCycleReactor 클래스를 이용해서 앱 오프닝 광고(app open ads)를 게재하는 단계입니다. 

 

 await MobileAds.instance.initialize();

우선 애드몹(admob) 광고를 게재하는 위해 main 함수에서  MobileAds.instance.initialize()으로 초기화를 시켜줍니다. 이건 어떤 애드몹 광고를 게재해도 해야되는 기본 옵션입니다. 

 

ref.read(appLifeCycleReactorProvider) 실행

initState() 에서 AppLifeCycleReactor를 리버팟을 이용해 실행하면 정상적으로 앱 오프닝 광고가 보일것 입니다. 

전체코드

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await MobileAds.instance.initialize();
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerStatefulWidget {
  const MyApp({super.key});

  @override
  ConsumerState<MyApp> createState() => _MyAppState();
}

class _MyAppState extends ConsumerState<MyApp> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    ref.read(appLifeCycleReactorProvider);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
        routerConfig: ref.watch(routerProvider),
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
            colorSchemeSeed: Colors.teal,
            useMaterial3: true,
            brightness: Brightness.light));
  }
}

완성된 앱 오프닝 광고

앱오프닝광고 app open ads
앱오프닝광고 app open ads

 
 


구글링 보단 챗GPT 

우선 이번 앱 오프닝 광고를 공부하면서 챗GPT에 도움을 많이 받았습니다. 기존에는 공식문서와 다른 사람이 적어둔 내용을 보고 공부했다면 플러터의 앱 오프닝 광고는 관련 자료를 찾는것이 상당히 어려웠습니다. 있어도 주로 유튜브에 영어로 된 자료가 대부분이라 중간중간 모르는 내용이 나오면 챗GPT에 물어보면서 하니 정말 쉽게 공부를 할 수 있었습니다. 

 

다만 chatGPT도 만능은 아닌지라 어느 정도 내용을 알아야 하는 부분이 있습니다. 종종 코드를 좀 틀리거나 아예 패키지에 없는 코드를 작성하는 경우가 있기 때문입니다. 

 

챗GPT는  개인 비서

그때 그때 모르는 것을 물어보면 바로 바로 답변해주어서 개인 비서처럼 사용가능하여 좋은거 같습니다. 사실 플러터는 자바나 코틀린 처럼 주류 언어가 아니기 때문에 모르는 것이 나올때마다 일일히 구글링해서 공부하는 것이 매우 어렵습니다. 하지만 ChatGPT는 그냥 제가 모르는것이 있을때마다 물어보면 정말 잘 대답해 줍니다. 

 

혹시나 새로운 공부 특히 코딩 공부를 시작하실 분들께 강추합니다. 

챗GPT 로 물어본 모습 

챗지피티&#44;chatGPT&#44;


참고 자료 

https://developers.google.com/admob/flutter/app-open?hl=en

 

앱 오프닝 광고     |  Flutter  |  Google for Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. Switch to English 앱 오프닝 광고 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 앱 오프닝 광고는 앱 로

developers.google.com

 
https://github.com/googleads/googleads-mobile-flutter/tree/main/samples/admob/app_open_example
 
 
 
 

댓글