백필 광고는 직광고가 없을 때 대체 광고를 자동으로 노출하여 수익을 극대화하는 기능입니다. Adrop은 AdMob, Pangle 등 주요 광고 네트워크를 백필 광고로 지원합니다.
백필 광고를 사용하려면 네이티브 플랫폼별로 추가 설정이 필요합니다.
Android 설정
1. Gradle 설정
settings.gradle.kts
Pangle 광고 네트워크 저장소를 추가합니다:
dependencyResolutionManagement {
repositoriesMode. set (RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google ()
mavenCentral ()
maven { url = uri ( "https://artifact.bytedance.com/repository/pangle" ) }
}
}
build.gradle.kts
백필 광고 의존성을 추가합니다:
build.gradle.kts (Module)
build.gradle (Module)
dependencies {
implementation ( "io.adrop:adrop-ads:1.7.2" )
implementation ( "io.adrop:adrop-ads-backfill:1.7.2" )
}
2. AndroidManifest.xml 설정
AdMob을 백필 광고로 사용하는 경우, AdMob App ID를 AndroidManifest.xml에 추가합니다:
< manifest >
< application >
<!-- AdMob App ID -->
< meta-data
android:name = "com.google.android.gms.ads.APPLICATION_ID"
android:value = "ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" />
</ application >
</ manifest >
ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy를 실제 AdMob App ID로 교체해야 합니다.
3. ProGuard 설정
ProGuard를 사용하는 경우 다음 규칙을 추가합니다:
-keep class io.adrop.** { *; }
-dontwarn io.adrop.**
iOS 설정
1. Podfile 수정
백필 광고 의존성을 Podfile에 추가합니다:
target 'Runner' do
use_frameworks!
use_modular_headers!
# Adrop SDK
pod 'adrop-ads'
# 백필 광고 SDK
pod 'adrop-ads-backfill'
flutter_install_all_ios_pods File . dirname ( File . realpath ( __FILE__ ))
end
의존성을 추가한 후 다음 명령어를 실행합니다:
cd ios && pod install --repo-update && cd ..
2. Info.plist 설정
AdMob을 백필 광고로 사용하는 경우, AdMob App ID를 Info.plist에 추가합니다:
< key > GADApplicationIdentifier </ key >
< string > ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy </ string >
ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy를 실제 AdMob App ID로 교체해야 합니다.
콘솔 설정
Adrop 콘솔에서 백필 광고를 활성화합니다:
애드컨트롤 콘솔 에 로그인
광고 유닛 메뉴로 이동
백필 광고를 사용할 광고 유닛 선택
백필 설정 섹션에서 백필 광고 활성화
사용할 백필 광고 네트워크 선택 (AdMob, Pangle 등)
광고 네트워크별 설정 입력 (예: AdMob Ad Unit ID)
Flutter에서 사용하기
백필 광고 확인
광고가 백필 광고인지 확인하려면 isBackfilled 프로퍼티를 사용합니다.
네이티브 광고
네이티브 광고의 경우, 백필 광고 여부에 따라 미디어 뷰를 다르게 렌더링해야 합니다.
import 'package:flutter/material.dart' ;
import 'package:adrop_ads_flutter/adrop_ads_flutter.dart' ;
import 'package:webview_flutter/webview_flutter.dart' ;
class NativeAdWithBackfill extends StatefulWidget {
const NativeAdWithBackfill ({ super .key});
@override
State < NativeAdWithBackfill > createState () => _NativeAdWithBackfillState ();
}
class _NativeAdWithBackfillState extends State < NativeAdWithBackfill > {
bool isLoaded = false ;
AdropNativeAd ? nativeAd;
late final WebViewController webViewController;
@override
void initState () {
super . initState ();
// WebView 컨트롤러 초기화
webViewController = WebViewController ()
.. setJavaScriptMode ( JavaScriptMode .unrestricted);
_createNativeAd ();
}
void _createNativeAd () {
nativeAd = AdropNativeAd (
unitId : 'YOUR_UNIT_ID' ,
useCustomClick : true ,
listener : AdropNativeListener (
onAdReceived : (ad) {
debugPrint ( '광고 수신: ${ ad . isBackfilled ? "백필" : "직광고" } ' );
// 직광고인 경우 WebView에 HTML 크리에이티브 로드
if ( ! ad.isBackfilled && ad.properties.creative != null ) {
webViewController. loadHtmlString (ad.properties.creative ! );
}
setState (() {
isLoaded = true ;
});
},
onAdFailedToReceive : (ad, errorCode) {
if (errorCode == AdropErrorCode .backfillNoFill) {
debugPrint ( '백필 광고도 없습니다' );
} else {
debugPrint ( '광고 로드 실패: $ errorCode ' );
}
},
),
);
nativeAd ? . load ();
}
@override
Widget build ( BuildContext context) {
if ( ! isLoaded) return const SizedBox . shrink ();
return AdropNativeAdView (
ad : nativeAd,
child : Container (
padding : const EdgeInsets . all ( 16 ),
child : Column (
crossAxisAlignment : CrossAxisAlignment .start,
children : [
// 헤드라인
if (nativeAd ? .properties.headline != null )
Text (
nativeAd ! .properties.headline ! ,
style : const TextStyle (
fontSize : 18 ,
fontWeight : FontWeight .bold,
),
),
const SizedBox (height : 8 ),
// 미디어 뷰 - 백필 여부에 따라 다르게 렌더링
_buildMediaView (),
// CTA 버튼
if (nativeAd ? .properties.callToAction != null )
Padding (
padding : const EdgeInsets . only (top : 8 ),
child : ElevatedButton (
onPressed : () {},
child : Text (nativeAd ! .properties.callToAction ! ),
),
),
],
),
),
);
}
Widget _buildMediaView () {
if (nativeAd ? .isBackfilled == true ) {
// 백필 광고: 이미지 에셋 사용
return Image . network (
nativeAd ? .properties.asset ?? '' ,
width : double .infinity,
height : 200 ,
fit : BoxFit .cover,
loadingBuilder : (context, child, loadingProgress) {
if (loadingProgress == null ) return child;
return const SizedBox (
height : 200 ,
child : Center (child : CircularProgressIndicator ()),
);
},
errorBuilder : (context, error, stackTrace) {
return const SizedBox (
height : 200 ,
child : Center (child : Icon ( Icons .error)),
);
},
);
} else if (nativeAd ? .properties.creative != null ) {
// 직광고: WebView로 HTML 크리에이티브 렌더링
return SizedBox (
width : double .infinity,
height : 300 ,
child : WebViewWidget (controller : webViewController),
);
} else {
return const SizedBox . shrink ();
}
}
}
네이티브 광고에서 백필 광고가 아닌 경우, 동영상 광고는 WebView를 사용하여 직접 렌더링해야 합니다.
배너 광고
배너 광고에서는 메타데이터를 통해 백필 여부를 확인할 수 있습니다.
bannerView = AdropBannerView (
unitId : 'YOUR_UNIT_ID' ,
listener : AdropBannerListener (
onAdReceived : (unitId, metadata) {
final isBackfilled = metadata ? [ 'isBackfilled' ] ?? false ;
if (isBackfilled == true ) {
debugPrint ( '백필 광고가 로드되었습니다' );
} else {
debugPrint ( '직광고가 로드되었습니다' );
}
},
onAdFailedToReceive : (unitId, errorCode) {
if (errorCode == AdropErrorCode .backfillNoFill) {
debugPrint ( '백필 광고도 없습니다' );
}
},
),
);
전면/리워드/팝업 광고
전면, 리워드, 팝업 광고에서도 유사하게 백필 여부를 확인할 수 있습니다.
interstitialAd = AdropInterstitialAd (
unitId : 'YOUR_UNIT_ID' ,
listener : AdropInterstitialListener (
onAdReceived : (ad) {
debugPrint ( '광고 로드 완료' );
// 전면 광고의 경우 별도의 isBackfilled 프로퍼티는 없지만
// 콘솔에서 백필 설정이 되어 있으면 자동으로 백필 광고가 로드됩니다
},
onAdFailedToReceive : (ad, errorCode) {
if (errorCode == AdropErrorCode .backfillNoFill) {
debugPrint ( '직광고와 백필 광고 모두 없습니다' );
}
},
),
);
광고 노출 흐름
백필 광고는 다음과 같은 순서로 노출됩니다:
에러 코드
백필 광고 관련 에러 코드입니다.
에러 코드 설명 adNoFill직광고를 받을 수 없음 (백필 광고 시도) backfillNoFill백필 광고도 받을 수 없음
onAdFailedToReceive : (ad, errorCode) {
switch (errorCode) {
case AdropErrorCode .adNoFill :
debugPrint ( '직광고가 없습니다. 백필 광고를 시도합니다.' );
break ;
case AdropErrorCode .backfillNoFill :
debugPrint ( '백필 광고도 없습니다.' );
break ;
default :
debugPrint ( '광고 로드 실패: ${ errorCode . code } ' );
}
}
지원 광고 형식
백필 광고는 다음 형식을 지원합니다:
광고 형식 지원 여부 설명 배너 (Banner) 지원 고정 크기 배너 광고 네이티브 (Native) 지원 커스터마이징 가능한 네이티브 광고 전면 (Interstitial) 지원 전체 화면 광고 리워드 (Rewarded) 지원 보상형 광고 팝업 (Popup) 지원 팝업 형태 광고
모범 사례
백필 광고 활성화 모든 광고 유닛에서 백필 광고를 활성화하여 광고 노출률과 수익을 극대화하세요.
적절한 타임아웃 설정 직광고와 백필 광고의 적절한 타임아웃을 설정하여 사용자 경험을 개선하세요.
백필 광고 분석 isBackfilled 프로퍼티를 사용하여 직광고와 백필 광고의 비율을 추적하고 분석하세요.
네이티브 광고 미디어 처리 네이티브 광고에서는 백필 여부에 따라 Image.network 또는 WebView를 적절히 사용하세요.
주의사항
Android: 백필 광고를 사용하려면 반드시 io.adrop:adrop-ads-backfill:1.7.2 의존성을 추가해야 합니다.
iOS: 백필 광고를 사용하려면 반드시 pod 'adrop-ads-backfill'를 Podfile에 추가해야 합니다.
AdMob을 사용하는 경우 각 플랫폼의 매니페스트 파일에 AdMob App ID를 반드시 추가해야 합니다.
네이티브 광고에서 백필 광고가 아닌 경우 WebView로 미디어를 렌더링해야 합니다.
백필 광고 네트워크의 정책을 준수해야 합니다.
다음 단계