AdMob

 

 

 

이번에는 앱에 광고를 삽입하자.

 

 

AdMob 게시와 관련된 공식 문서

https://developers.google.com/admob/flutter/quick-start?hl=ko

 

시작하기  |  Flutter  |  Google for Developers

Flutter 앱을 제작 중인 AdMob 게시자를 위한 모바일 광고 SDK입니다.

developers.google.com

 

 

Flutter에서 AdMob을 사용을 도와주는 패키지

https://pub.dev/packages/google_mobile_ads

 

google_mobile_ads | Flutter Package

Flutter plugin for Google Mobile Ads, supporting banner, interstitial (full-screen), rewarded and native ads

pub.dev

 

 

 

앱 광고의 종류는 배너 광고, 전면 광고, 네이티브 광고, 보상형 광고 이렇게 4가지가 존재한다.

 

  1. 배너 광고 : 앱 화면의 상단이나 하단에 표시되는 광고
  2. 전면 광고 : 전체 화면 광고
  3. 네이티브 광고 : 앱의 디자인과 분위기 어울리도록 맞춤 설정이 가능한 광고
  4. 보상형 광고 : 동영상 광고 시청이나 설문 조사 등을 진행하고 사용자에게 보상을 제공하는 광고

 

 

내가 광고를 넣을 곳은 다음과 같다.

  1. 앱 메인 화면의 아래 부분
  2. 최신 영화 데이터 업데이트 시 
  3. 앱 종료 시

 

1번과 3번은 배너 광고를 사용하고 2번은 보상형 광고를 사용하도록 한다.

 

 

최신 영화 데이터 업데이트 시에는 광고 삽입이 반 필수적이다.

왜냐하면 Firestore에서 최신 영화 정보를 가져오는 것에 대한 요금이 발생하기 때문이다.

(물론 무료 사용량이 여유롭긴 하지만 내 지갑에서 돈 나가는 건 피하고 싶기 때문에 ㅎㅎ)

 

 

 

소스코드

 

AdMob 클래스를 만들고, 광고 id 변수와 AdMob 광고 인스턴스를 생성한다.

setAdUnitId 함수는 app_config.json에 있는 광고 id를 읽어와 광고 id 변수에 값을 할당한다.

class AdMob {
  // test bannerAdUnitId
  static String bannerAdUnitId='';

  // test rewardAdUnitId
  static String rewardAdUnitId='';

  // test exitAdUnitId
  static String exitAdUnitId='';

  static BannerAd? anchoredAdaptiveAd;

  static RewardedAd? rewardedAd;

  static BannerAd? exitAd;

  static Future<void> setAdUnitId() async {

    // app_config 에서 admob id 가져옴
    String jsonString = await rootBundle.loadString('assets/app_config.json');

    Map<String, dynamic> jsonData = json.decode(jsonString);

    bannerAdUnitId = jsonData["bannerAdUnitId"];
    rewardAdUnitId = jsonData["rewardAdUnitId"];
    exitAdUnitId = jsonData["exitAdUnitId"];

    }
  }

 

 

 

아래의 함수는 메인 화면의 아래에 들어가는 광고에 관한 함수이다.

여기서 사용한 광고는 앵커형 배너 광고로 사용자의 디바이스 크기에 맞게 광고를 게시한다.

static Future<BannerAd?> loadBannerAd(BuildContext context) async {
  // 앵커형 배너 사이즈
  AnchoredAdaptiveBannerAdSize? size =
      await AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(
          MediaQuery.of(context).size.width.truncate());

  anchoredAdaptiveAd = BannerAd(
    adUnitId: bannerAdUnitId,
    request: const AdRequest(),
    size: size ?? AdSize.banner,
    listener: BannerAdListener(
      onAdLoaded: (Ad ad) {
        print('$ad loaded.');
      },
      onAdFailedToLoad: (Ad ad, LoadAdError error) {
        print('$ad failed.');
        ad.dispose();
      },
    ),
  )..load();
  return anchoredAdaptiveAd;
}

static Container showBannerAd() {
  Container ad = Container(
    decoration: const BoxDecoration(
      color: Colors.white,
    ),
    child: Align(
      alignment: Alignment.bottomCenter,
      child: SafeArea(
        child: SizedBox(
          width: anchoredAdaptiveAd!.size.width.toDouble(),
          height: anchoredAdaptiveAd!.size.height.toDouble(),
          child: AdWidget(ad: anchoredAdaptiveAd!),
        ),
      ),
    ),
  );

  return ad;
}

 

 

아래에 배너 광고

 

 

다음은 앱 종료 시의 광고다.

static void loadExitAd(int width, int height){
  exitAd = BannerAd(
    adUnitId: exitAdUnitId,
    request: const AdRequest(),
    size:  AdSize(width: width, height: height),
    listener: BannerAdListener(
      onAdLoaded: (Ad ad) {
        print('$ad loaded.');
      },
      onAdFailedToLoad: (Ad ad, LoadAdError error) {
        print('$ad failed.');
        ad.dispose();
      },
    ),
  )..load();
}

static Widget showExitAd(){
  Widget ad = SizedBox(
    width: exitAd!.size.width.toDouble(),
    height: exitAd!.size.height.toDouble(),
    child: AdWidget(ad: exitAd!),
  );
  return ad;
}

 

 

앱 종료 시의 광고

 

 

 

다음은 최신 영화 데이터 업데이트 시의 광고다.

static void loadRewardAd() {
  RewardedAd.load(
      adUnitId: rewardAdUnitId,
      request: const AdRequest(),
      rewardedAdLoadCallback: RewardedAdLoadCallback(
        onAdLoaded: (ad) {
          print('$ad loaded.');

          // rewardedAd.show() 함수를 통해 보상형 광고 보여줌 (update.dart에 구현)
          rewardedAd = ad;
        },
        onAdFailedToLoad: (LoadAdError error) {
          debugPrint('RewardedAd failed to load: $error');
        },
      ));

}

 

 

 

rewardedAd.show() 함수를 사용하여 광고를 다 보면 업데이트가 진행되도록 하였다.

# update_page.dart 소스파일의 일부분 가져옴

AdMob.rewardedAd?.show(onUserEarnedReward: (AdWithoutView ad, RewardItem reward) async{

  // 다시 누를 수도 있으니 리워드 광고를 다시 load
  AdMob.loadRewardAd();

  Navigator.push(
    context,
    MaterialPageRoute(
        builder: (context) => const UpdateLoadingPage()),
  );
  var downloadedDataNum = await updateMovieInfo();

  Navigator.pop(context);
  setState(() {});
  doneDialog(downloadedDataNum);
});

 

 

업데이트 버튼 클릭시 리워드 광고 실행

 

 

 

 

광고 ID

앱 개발 중 광고를 테스트할 때는 테스트 ID를 사용하자. 

실제로 서비스에 출시할 광고 ID로 잦은 테스트를 할 경우 부정 사용으로 간주하여 정지를 먹을 수 있다.

(구글에 보니까 피해자? 들이 많더라)

 

Android

앱 오프닝 광고 ca-app-pub-3940256099942544/3419835294
적응형 배너 ca-app-pub-3940256099942544/9214589741
배너 ca-app-pub-3940256099942544/6300978111
전면 광고 ca-app-pub-3940256099942544/1033173712
동영상 전면 광고 ca-app-pub-3940256099942544/8691691433
보상형 광고 ca-app-pub-3940256099942544/5224354917
보상형 전면 광고 ca-app-pub-3940256099942544/5354046379
네이티브 광고 고급형 ca-app-pub-3940256099942544/2247696110
네이티브 광고 고급형 동영상 ca-app-pub-3940256099942544/1044960115

 

 

IOS

앱 오프닝 광고 ca-app-pub-3940256099942544/5662855259
적응형 배너 ca-app-pub-3940256099942544/2435281174
배너 ca-app-pub-3940256099942544/2934735716
전면 광고 ca-app-pub-3940256099942544/4411468910
동영상 전면 광고 ca-app-pub-3940256099942544/5135589807
보상형 광고 ca-app-pub-3940256099942544/1712485313
보상형 전면 광고 ca-app-pub-3940256099942544/6978759866
네이티브 광고 고급형 ca-app-pub-3940256099942544/3986624511
네이티브 광고 고급형 동영상 ca-app-pub-3940256099942544/2521693316

 

 

실제 서비스에 사용할 광고 ID를 발급받으려면 AdMob에 가입하고, 앱을 추가하고, 광고 단위를 추가하면 ID를 얻을 수 있다.

 

 

우선 아래의 링크에서 AdMob에 가입한다.

https://admob.google.com/intl/ko/home/

 

Google AdMob: 모바일 앱 수익 창출

인앱 광고를 사용하여 모바일 앱에서 더 많은 수익을 창출하고, 사용이 간편한 도구를 통해 유용한 분석 정보를 얻고 앱을 성장시켜 보세요.

admob.google.com

 

 

 

앱 추가 버튼을 클릭하여 앱을 추가한다.

 

 

 

광고 단위 추가 버튼을 클릭하고 원하는 광고 유형을 선택하고 생성하면 광고 단위 ID를 얻을 수 있다.

 

 

 

이렇게 해서 앱에 광고를 넣는 것까지 끝났다.