개요
전면 광고(Interstitial Ad)는 앱의 화면 전체를 덮는 형태로 표시되는 광고입니다. 게임의 레벨 전환, 콘텐츠 페이지 전환 등 앱의 자연스러운 전환 시점에 표시하기 적합합니다.특징
- 전체 화면을 덮는 몰입형 광고
- 사용자가 명시적으로 닫기 전까지 유지
- 이미지 및 동영상 광고 지원
- 높은 시각적 주목도
개발 환경에서는 테스트 유닛 ID를 사용하세요:
PUBLIC_TEST_UNIT_ID_INTERSTITIAL구현 단계
전면 광고는 다음 4단계로 구현합니다:- 초기화 - AdropInterstitialAd 인스턴스 생성
- 리스너 설정 - 광고 이벤트 수신을 위한 리스너 설정
- 광고 로드 - 광고 요청 및 수신
- 광고 표시 - 화면에 광고 표시
기본 구현
AdropInterstitialAd 인스턴스 생성
import io.adrop.ads.interstitial.AdropInterstitialAd
class MainActivity : AppCompatActivity() {
private var interstitialAd: AdropInterstitialAd? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 1. 전면 광고 인스턴스 생성
interstitialAd = AdropInterstitialAd(this, "YOUR_UNIT_ID")
}
}
import io.adrop.ads.interstitial.AdropInterstitialAd;
public class MainActivity extends AppCompatActivity {
private AdropInterstitialAd interstitialAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1. 전면 광고 인스턴스 생성
interstitialAd = new AdropInterstitialAd(this, "YOUR_UNIT_ID");
}
}
AdropInterstitialAd 생성자
Android Context 객체 (Activity 또는 Application Context)
광고 유닛 ID (콘솔에서 발급)
리스너 설정
광고 이벤트를 수신하려면AdropInterstitialAdListener를 구현하고 설정해야 합니다.
import io.adrop.ads.interstitial.AdropInterstitialAdListener
import io.adrop.ads.model.AdropErrorCode
class MainActivity : AppCompatActivity() {
private var interstitialAd: AdropInterstitialAd? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 1. 전면 광고 인스턴스 생성
interstitialAd = AdropInterstitialAd(this, "YOUR_UNIT_ID")
// 2. 리스너 설정
interstitialAd?.interstitialAdListener = object : AdropInterstitialAdListener {
override fun onAdReceived(ad: AdropInterstitialAd) {
Log.d("Adrop", "전면 광고 수신 완료")
}
override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
Log.e("Adrop", "전면 광고 수신 실패: $errorCode")
}
override fun onAdImpression(ad: AdropInterstitialAd) {
Log.d("Adrop", "전면 광고 노출")
}
override fun onAdClicked(ad: AdropInterstitialAd) {
Log.d("Adrop", "전면 광고 클릭")
}
override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
Log.d("Adrop", "전면 광고 표시 직전")
}
override fun onAdDidPresentFullScreen(ad: AdropInterstitialAd) {
Log.d("Adrop", "전면 광고 표시 완료")
}
override fun onAdWillDismissFullScreen(ad: AdropInterstitialAd) {
Log.d("Adrop", "전면 광고 닫히기 직전")
}
override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
Log.d("Adrop", "전면 광고 닫힘")
// 다음 광고를 미리 로드
loadInterstitialAd()
}
override fun onAdFailedToShowFullScreen(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
Log.e("Adrop", "전면 광고 표시 실패: $errorCode")
}
}
// 2-1. 백버튼 콜백 리스너 설정
interstitialAd?.closeListener = object : AdropInterstitialAdCloseListener {
override fun onBackPressed(ad: AdropInterstitialAd) {
Log.d("Adrop", "뒤로가기 버튼 클릭")
}
}
// 3. 광고 로드
loadInterstitialAd()
}
private fun loadInterstitialAd() {
interstitialAd?.load()
}
}
import io.adrop.ads.interstitial.AdropInterstitialAdListener;
import io.adrop.ads.model.AdropErrorCode;
public class MainActivity extends AppCompatActivity {
private AdropInterstitialAd interstitialAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1. 전면 광고 인스턴스 생성
interstitialAd = new AdropInterstitialAd(this, "YOUR_UNIT_ID");
// 2. 리스너 설정
interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
@Override
public void onAdReceived(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "전면 광고 수신 완료");
}
@Override
public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
Log.e("Adrop", "전면 광고 수신 실패: " + errorCode);
}
@Override
public void onAdImpression(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "전면 광고 노출");
}
@Override
public void onAdClicked(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "전면 광고 클릭");
}
@Override
public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "전면 광고 표시 직전");
}
@Override
public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "전면 광고 표시 완료");
}
@Override
public void onAdWillDismissFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "전면 광고 닫히기 직전");
}
@Override
public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "전면 광고 닫힘");
// 다음 광고를 미리 로드
loadInterstitialAd();
}
@Override
public void onAdFailedToShowFullScreen(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
Log.e("Adrop", "전면 광고 표시 실패: " + errorCode);
}
});
// 2-1. 백버튼 콜백 리스너 설정
interstitialAd.setCloseListener(new AdropInterstitialAdCloseListener() {
@Override
public void onBackPressed(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "뒤로가기 버튼 클릭");
}
});
// 3. 광고 로드
loadInterstitialAd();
}
private void loadInterstitialAd() {
interstitialAd.load();
}
}
광고 로드
load() 메서드를 호출하여 광고를 요청합니다.
private fun loadInterstitialAd() {
interstitialAd?.load()
}
private void loadInterstitialAd() {
interstitialAd.load();
}
onAdReceived 콜백이 호출되며, 실패 시 onAdFailedToReceive 콜백이 호출됩니다.
광고 표시
광고가 로드된 후show() 메서드를 호출하여 광고를 표시합니다.
isLoaded 프로퍼티
광고가 로드되었는지 확인하는 프로퍼티입니다.show() 호출 전에 이 값을 확인하는 것이 좋습니다.
private fun showInterstitialAd() {
if (interstitialAd?.isLoaded == true) {
interstitialAd?.show(this)
} else {
Log.d("Adrop", "광고가 아직 로드되지 않았습니다")
}
}
private void showInterstitialAd() {
if (interstitialAd != null && interstitialAd.isLoaded()) {
interstitialAd.show(this);
} else {
Log.d("Adrop", "광고가 아직 로드되지 않았습니다");
}
}
show 메서드
광고를 표시할 Activity 객체
AdropInterstitialAd 프로퍼티
unitId
광고 유닛 ID를 반환합니다.val unitId: String = interstitialAd?.unitId ?: ""
String unitId = interstitialAd.getUnitId();
isLoaded
광고가 로드되었는지 여부를 반환합니다.val isLoaded: Boolean = interstitialAd?.isLoaded ?: false
boolean isLoaded = interstitialAd.isLoaded();
creativeId
현재 로드된 광고의 크리에이티브 ID를 반환합니다.val creativeId: String = interstitialAd?.creativeId ?: ""
String creativeId = interstitialAd.getCreativeId();
txId
현재 로드된 광고의 트랜잭션 ID를 반환합니다.val txId: String = interstitialAd?.txId ?: ""
String txId = interstitialAd.getTxId();
campaignId
현재 로드된 광고의 캠페인 ID를 반환합니다.val campaignId: String = interstitialAd?.campaignId ?: ""
String campaignId = interstitialAd.getCampaignId();
isBackfilled
현재 로드된 광고가 백필 광고인지 여부를 반환합니다.val isBackfilled: Boolean = interstitialAd?.isBackfilled ?: false
boolean isBackfilled = interstitialAd.isBackfilled();
close()
프로그래밍 방식으로 전면 광고를 닫습니다.interstitialAd?.close()
interstitialAd.close();
AdropInterstitialAdListener 메서드
필수 메서드
광고 수신 성공 시 호출됩니다. 이 시점에서
show()를 호출하여 광고를 표시할 수 있습니다.광고 수신 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
선택 메서드
광고 노출이 기록되었을 때 호출됩니다.
사용자가 광고를 클릭했을 때 호출됩니다.
전면 광고가 표시되기 직전에 호출됩니다. 게임 일시정지 등의 작업을 수행할 수 있습니다.
전면 광고가 화면에 표시된 직후 호출됩니다.
전면 광고가 닫히기 직전에 호출됩니다.
전면 광고가 닫힌 직후 호출됩니다. 다음 광고를 미리 로드하기 좋은 시점입니다.
광고 표시 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
백버튼 콜백
전면 광고가 표시된 상태에서 사용자가 뒤로가기 버튼을 누르면AdropInterstitialAdCloseListener를 통해 콜백을 받을 수 있습니다.
AdropInterstitialAdCloseListener
사용자가 전면 광고에서 뒤로가기 버튼을 눌렀을 때 호출됩니다.
사용 예시
import io.adrop.ads.interstitial.AdropInterstitialAd
import io.adrop.ads.interstitial.AdropInterstitialAdCloseListener
// 1. closeListener 정의
private val closeListener = object : AdropInterstitialAdCloseListener {
override fun onBackPressed(ad: AdropInterstitialAd) {
// 사용자가 뒤로가기 버튼을 눌렀을 때 호출됩니다
Log.d("InterstitialAd", "Back button pressed")
// 광고를 닫으려면 close()를 호출하세요
ad.close()
}
}
// 2. 전면 광고 생성 시 closeListener 설정
val interstitialAd = AdropInterstitialAd(context, "YOUR_UNIT_ID").apply {
interstitialAdListener = yourAdListener
closeListener = this@YourActivity.closeListener
load()
}
import io.adrop.ads.interstitial.AdropInterstitialAd;
import io.adrop.ads.interstitial.AdropInterstitialAdCloseListener;
import io.adrop.ads.interstitial.AdropInterstitialAdListener;
// 1. closeListener 정의
private final AdropInterstitialAdCloseListener closeListener = new AdropInterstitialAdCloseListener() {
@Override
public void onBackPressed(@NonNull AdropInterstitialAd ad) {
// 사용자가 뒤로가기 버튼을 눌렀을 때 호출됩니다
Log.d("InterstitialAd", "Back button pressed");
// 광고를 닫으려면 close()를 호출하세요
ad.close();
}
};
// 2. 전면 광고 생성 시 closeListener 설정
AdropInterstitialAd interstitialAd = new AdropInterstitialAd(context, "YOUR_UNIT_ID");
interstitialAd.setInterstitialAdListener(yourAdListener);
interstitialAd.setCloseListener(closeListener); // 새로 추가
interstitialAd.load();
동작 설명
- 백버튼 콜백: 사용자가 뒤로가기 버튼을 누르면
closeListener.onBackPressed()가 먼저 호출됩니다. - 자동 닫힘 조건: 광고가 표시된 후 30초 이상 경과하거나, WebView가 없는 경우 백버튼 시 자동으로 광고가 닫힙니다.
- 수동 닫기:
ad.close()를 호출하면 언제든 프로그래밍 방식으로 광고를 닫을 수 있습니다. - closeListener를 설정하지 않으면: 기존 동작과 동일하게 30초 후 자동 닫힘만 동작합니다.
Android 15+ 호환성
Android 13(Tiramisu) 이상에서OnBackInvokedCallback을 사용하여 예측형 뒤로가기(Predictive Back)를 지원합니다. 앱에서 enableOnBackInvokedCallback="true"를 설정한 경우에도 정상 동작합니다.
<!-- AndroidManifest.xml -->
<application
android:enableOnBackInvokedCallback="true"
... >
생명주기 관리
destroy 메서드
Activity나 Fragment가 종료될 때destroy() 메서드를 호출하여 리소스를 해제해야 합니다.
override fun onDestroy() {
super.onDestroy()
interstitialAd?.destroy()
interstitialAd = null
}
@Override
protected void onDestroy() {
super.onDestroy();
if (interstitialAd != null) {
interstitialAd.destroy();
interstitialAd = null;
}
}
메모리 누수를 방지하기 위해 반드시
destroy()를 호출하세요.사전 로드 전략
사용자 경험을 향상시키기 위해 광고를 미리 로드하는 것이 좋습니다.기본 사전 로드
class GameActivity : AppCompatActivity() {
private var interstitialAd: AdropInterstitialAd? = null
private var isAdReady = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_game)
// 화면 진입 시 미리 로드
preloadInterstitialAd()
}
private fun preloadInterstitialAd() {
interstitialAd = AdropInterstitialAd(this, "YOUR_UNIT_ID")
interstitialAd?.interstitialAdListener = object : AdropInterstitialAdListener {
override fun onAdReceived(ad: AdropInterstitialAd) {
isAdReady = true
Log.d("Adrop", "전면 광고 준비 완료")
}
override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
isAdReady = false
Log.e("Adrop", "전면 광고 로드 실패: $errorCode")
}
override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
isAdReady = false
// 다음 광고 미리 로드
preloadInterstitialAd()
}
}
interstitialAd?.load()
}
private fun onGameLevelComplete() {
// 레벨 완료 시 즉시 표시
if (isAdReady) {
interstitialAd?.show(this)
}
}
}
public class GameActivity extends AppCompatActivity {
private AdropInterstitialAd interstitialAd;
private boolean isAdReady = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
// 화면 진입 시 미리 로드
preloadInterstitialAd();
}
private void preloadInterstitialAd() {
interstitialAd = new AdropInterstitialAd(this, "YOUR_UNIT_ID");
interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
@Override
public void onAdReceived(@NonNull AdropInterstitialAd ad) {
isAdReady = true;
Log.d("Adrop", "전면 광고 준비 완료");
}
@Override
public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
isAdReady = false;
Log.e("Adrop", "전면 광고 로드 실패: " + errorCode);
}
@Override
public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
isAdReady = false;
// 다음 광고 미리 로드
preloadInterstitialAd();
}
});
interstitialAd.load();
}
private void onGameLevelComplete() {
// 레벨 완료 시 즉시 표시
if (isAdReady) {
interstitialAd.show(this);
}
}
}
닫기 후 재로드
광고가 닫힌 후onAdDidDismissFullScreen 콜백에서 다음 광고를 미리 로드합니다.
override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
Log.d("Adrop", "전면 광고 닫힘")
// 즉시 다음 광고 로드
interstitialAd?.load()
}
@Override
public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "전면 광고 닫힘");
// 즉시 다음 광고 로드
interstitialAd.load();
}
모범 사례
1. 적절한 표시 시점
앱의 자연스러운 전환 시점에 광고를 표시하세요.// ✅ 좋은 예: 게임 레벨 전환
fun onLevelComplete() {
saveProgress()
showInterstitialAd()
loadNextLevel()
}
// ✅ 좋은 예: 콘텐츠 읽기 완료
fun onArticleFinished() {
showInterstitialAd()
}
// ❌ 나쁜 예: 사용자 액션 중간
fun onButtonClick() {
showInterstitialAd() // 사용자 경험 저해
performAction()
}
// ✅ 좋은 예: 게임 레벨 전환
private void onLevelComplete() {
saveProgress();
showInterstitialAd();
loadNextLevel();
}
// ✅ 좋은 예: 콘텐츠 읽기 완료
private void onArticleFinished() {
showInterstitialAd();
}
// ❌ 나쁜 예: 사용자 액션 중간
private void onButtonClick() {
showInterstitialAd(); // 사용자 경험 저해
performAction();
}
2. 에러 처리
광고 로드 실패에 대비한 처리를 구현하세요.override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
when (errorCode) {
AdropErrorCode.ERROR_CODE_NETWORK -> {
Log.e("Adrop", "네트워크 오류: 나중에 다시 시도")
retryAfterDelay()
}
AdropErrorCode.ERROR_CODE_AD_NO_FILL -> {
Log.w("Adrop", "표시할 광고 없음")
continueWithoutAd()
}
else -> {
Log.e("Adrop", "광고 로드 실패: $errorCode")
}
}
}
private fun retryAfterDelay() {
Handler(Looper.getMainLooper()).postDelayed({
interstitialAd?.load()
}, 30000) // 30초 후 재시도
}
private fun continueWithoutAd() {
// 광고 없이 계속 진행
proceedToNextScreen()
}
@Override
public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
switch (errorCode) {
case ERROR_CODE_NETWORK:
Log.e("Adrop", "네트워크 오류: 나중에 다시 시도");
retryAfterDelay();
break;
case ERROR_CODE_AD_NO_FILL:
Log.w("Adrop", "표시할 광고 없음");
continueWithoutAd();
break;
default:
Log.e("Adrop", "광고 로드 실패: " + errorCode);
break;
}
}
private void retryAfterDelay() {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
interstitialAd.load();
}, 30000); // 30초 후 재시도
}
private void continueWithoutAd() {
// 광고 없이 계속 진행
proceedToNextScreen();
}
3. 빈도 제한
너무 자주 광고를 표시하지 않도록 제한하세요.class AdFrequencyManager {
private var lastAdShownTime: Long = 0
private val minimumInterval = 180_000L // 3분
fun canShowAd(): Boolean {
val currentTime = System.currentTimeMillis()
return currentTime - lastAdShownTime >= minimumInterval
}
fun recordAdShown() {
lastAdShownTime = System.currentTimeMillis()
}
}
// 사용 예시
class MainActivity : AppCompatActivity() {
private val frequencyManager = AdFrequencyManager()
private fun showInterstitialIfAllowed() {
if (!frequencyManager.canShowAd()) {
Log.d("Adrop", "광고 표시 간격이 너무 짧음")
return
}
interstitialAd?.show(this)
}
// 리스너에서 호출
override fun onAdDidPresentFullScreen(ad: AdropInterstitialAd) {
frequencyManager.recordAdShown()
}
}
public class AdFrequencyManager {
private long lastAdShownTime = 0;
private final long minimumInterval = 180_000L; // 3분
public boolean canShowAd() {
long currentTime = System.currentTimeMillis();
return currentTime - lastAdShownTime >= minimumInterval;
}
public void recordAdShown() {
lastAdShownTime = System.currentTimeMillis();
}
}
// 사용 예시
public class MainActivity extends AppCompatActivity {
private final AdFrequencyManager frequencyManager = new AdFrequencyManager();
private void showInterstitialIfAllowed() {
if (!frequencyManager.canShowAd()) {
Log.d("Adrop", "광고 표시 간격이 너무 짧음");
return;
}
interstitialAd.show(this);
}
// 리스너에서 호출
@Override
public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
frequencyManager.recordAdShown();
}
}
4. 게임 일시정지 처리
전면 광고 표시 시 게임이나 애니메이션을 일시정지하세요.override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
// 게임 일시정지
pauseGame()
// 배경음악 중지
pauseBackgroundMusic()
}
override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
// 게임 재개
resumeGame()
// 배경음악 재생
resumeBackgroundMusic()
}
@Override
public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
// 게임 일시정지
pauseGame();
// 배경음악 중지
pauseBackgroundMusic();
}
@Override
public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
// 게임 재개
resumeGame();
// 배경음악 재생
resumeBackgroundMusic();
}
테스트
테스트 유닛 ID 사용
개발 중에는 테스트 유닛 ID를 사용하세요.import io.adrop.ads.AdropAds
class MainActivity : AppCompatActivity() {
private val unitId = if (BuildConfig.DEBUG) {
"PUBLIC_TEST_UNIT_ID_INTERSTITIAL"
} else {
"YOUR_PRODUCTION_UNIT_ID"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
interstitialAd = AdropInterstitialAd(this, unitId)
}
}
public class MainActivity extends AppCompatActivity {
private final String unitId = BuildConfig.DEBUG ?
"PUBLIC_TEST_UNIT_ID_INTERSTITIAL" :
"YOUR_PRODUCTION_UNIT_ID";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
interstitialAd = new AdropInterstitialAd(this, unitId);
}
}
광고 로드 확인
광고가 정상적으로 로드되는지 확인하세요.override fun onAdReceived(ad: AdropInterstitialAd) {
Log.d("Adrop", "✅ 전면 광고 로드 성공")
Log.d("Adrop", "Unit ID: ${ad.unitId}")
Log.d("Adrop", "Creative ID: ${ad.creativeId}")
Log.d("Adrop", "Is Backfilled: ${ad.isBackfilled}")
}
override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
Log.e("Adrop", "❌ 전면 광고 로드 실패: $errorCode")
if (BuildConfig.DEBUG) {
Toast.makeText(this, "광고 로드 실패: $errorCode", Toast.LENGTH_SHORT).show()
}
}
@Override
public void onAdReceived(@NonNull AdropInterstitialAd ad) {
Log.d("Adrop", "✅ 전면 광고 로드 성공");
Log.d("Adrop", "Unit ID: " + ad.getUnitId());
Log.d("Adrop", "Creative ID: " + ad.getCreativeId());
Log.d("Adrop", "Is Backfilled: " + ad.isBackfilled());
}
@Override
public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
Log.e("Adrop", "❌ 전면 광고 로드 실패: " + errorCode);
if (BuildConfig.DEBUG) {
Toast.makeText(this, "광고 로드 실패: " + errorCode, Toast.LENGTH_SHORT).show();
}
}
완전한 구현 예제
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import io.adrop.ads.interstitial.AdropInterstitialAd
import io.adrop.ads.interstitial.AdropInterstitialAdListener
import io.adrop.ads.model.AdropErrorCode
class InterstitialAdActivity : AppCompatActivity() {
private var interstitialAd: AdropInterstitialAd? = null
private lateinit var loadButton: Button
private lateinit var showButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_interstitial_ad)
loadButton = findViewById(R.id.btn_load_ad)
showButton = findViewById(R.id.btn_show_ad)
// 버튼 초기 상태 설정
showButton.isEnabled = false
// 전면 광고 초기화
setupInterstitialAd()
// 버튼 클릭 리스너
loadButton.setOnClickListener {
loadInterstitialAd()
}
showButton.setOnClickListener {
showInterstitialAd()
}
// 자동으로 첫 광고 로드
loadInterstitialAd()
}
private fun setupInterstitialAd() {
val unitId = if (BuildConfig.DEBUG) {
"PUBLIC_TEST_UNIT_ID_INTERSTITIAL"
} else {
"YOUR_PRODUCTION_UNIT_ID"
}
interstitialAd = AdropInterstitialAd(this, unitId)
interstitialAd?.interstitialAdListener = object : AdropInterstitialAdListener {
override fun onAdReceived(ad: AdropInterstitialAd) {
Log.d(TAG, "전면 광고 수신 완료")
showButton.isEnabled = true
loadButton.isEnabled = false
Toast.makeText(
this@InterstitialAdActivity,
"광고가 준비되었습니다",
Toast.LENGTH_SHORT
).show()
}
override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
Log.e(TAG, "전면 광고 수신 실패: $errorCode")
showButton.isEnabled = false
loadButton.isEnabled = true
Toast.makeText(
this@InterstitialAdActivity,
"광고 로드 실패: $errorCode",
Toast.LENGTH_SHORT
).show()
}
override fun onAdImpression(ad: AdropInterstitialAd) {
Log.d(TAG, "전면 광고 노출")
}
override fun onAdClicked(ad: AdropInterstitialAd) {
Log.d(TAG, "전면 광고 클릭")
}
override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
Log.d(TAG, "전면 광고 표시 직전")
}
override fun onAdDidPresentFullScreen(ad: AdropInterstitialAd) {
Log.d(TAG, "전면 광고 표시 완료")
}
override fun onAdWillDismissFullScreen(ad: AdropInterstitialAd) {
Log.d(TAG, "전면 광고 닫히기 직전")
}
override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
Log.d(TAG, "전면 광고 닫힘")
showButton.isEnabled = false
loadButton.isEnabled = true
Toast.makeText(
this@InterstitialAdActivity,
"광고가 닫혔습니다",
Toast.LENGTH_SHORT
).show()
// 다음 광고를 미리 로드
loadInterstitialAd()
}
override fun onAdFailedToShowFullScreen(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
Log.e(TAG, "전면 광고 표시 실패: $errorCode")
showButton.isEnabled = false
loadButton.isEnabled = true
Toast.makeText(
this@InterstitialAdActivity,
"광고 표시 실패: $errorCode",
Toast.LENGTH_SHORT
).show()
}
}
}
private fun loadInterstitialAd() {
Log.d(TAG, "전면 광고 로드 시작")
loadButton.isEnabled = false
interstitialAd?.load()
}
private fun showInterstitialAd() {
if (interstitialAd?.isLoaded == true) {
Log.d(TAG, "전면 광고 표시")
interstitialAd?.show(this)
} else {
Log.w(TAG, "광고가 아직 로드되지 않았습니다")
Toast.makeText(this, "광고가 준비되지 않았습니다", Toast.LENGTH_SHORT).show()
}
}
override fun onDestroy() {
super.onDestroy()
interstitialAd?.destroy()
interstitialAd = null
}
companion object {
private const val TAG = "InterstitialAdActivity"
}
}
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import io.adrop.ads.interstitial.AdropInterstitialAd;
import io.adrop.ads.interstitial.AdropInterstitialAdListener;
import io.adrop.ads.model.AdropErrorCode;
public class InterstitialAdActivity extends AppCompatActivity {
private static final String TAG = "InterstitialAdActivity";
private AdropInterstitialAd interstitialAd;
private Button loadButton;
private Button showButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_interstitial_ad);
loadButton = findViewById(R.id.btn_load_ad);
showButton = findViewById(R.id.btn_show_ad);
// 버튼 초기 상태 설정
showButton.setEnabled(false);
// 전면 광고 초기화
setupInterstitialAd();
// 버튼 클릭 리스너
loadButton.setOnClickListener(v -> loadInterstitialAd());
showButton.setOnClickListener(v -> showInterstitialAd());
// 자동으로 첫 광고 로드
loadInterstitialAd();
}
private void setupInterstitialAd() {
String unitId = BuildConfig.DEBUG ?
"PUBLIC_TEST_UNIT_ID_INTERSTITIAL" :
"YOUR_PRODUCTION_UNIT_ID";
interstitialAd = new AdropInterstitialAd(this, unitId);
interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
@Override
public void onAdReceived(@NonNull AdropInterstitialAd ad) {
Log.d(TAG, "전면 광고 수신 완료");
showButton.setEnabled(true);
loadButton.setEnabled(false);
Toast.makeText(
InterstitialAdActivity.this,
"광고가 준비되었습니다",
Toast.LENGTH_SHORT
).show();
}
@Override
public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
Log.e(TAG, "전면 광고 수신 실패: " + errorCode);
showButton.setEnabled(false);
loadButton.setEnabled(true);
Toast.makeText(
InterstitialAdActivity.this,
"광고 로드 실패: " + errorCode,
Toast.LENGTH_SHORT
).show();
}
@Override
public void onAdImpression(@NonNull AdropInterstitialAd ad) {
Log.d(TAG, "전면 광고 노출");
}
@Override
public void onAdClicked(@NonNull AdropInterstitialAd ad) {
Log.d(TAG, "전면 광고 클릭");
}
@Override
public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d(TAG, "전면 광고 표시 직전");
}
@Override
public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d(TAG, "전면 광고 표시 완료");
}
@Override
public void onAdWillDismissFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d(TAG, "전면 광고 닫히기 직전");
}
@Override
public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
Log.d(TAG, "전면 광고 닫힘");
showButton.setEnabled(false);
loadButton.setEnabled(true);
Toast.makeText(
InterstitialAdActivity.this,
"광고가 닫혔습니다",
Toast.LENGTH_SHORT
).show();
// 다음 광고를 미리 로드
loadInterstitialAd();
}
@Override
public void onAdFailedToShowFullScreen(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
Log.e(TAG, "전면 광고 표시 실패: " + errorCode);
showButton.setEnabled(false);
loadButton.setEnabled(true);
Toast.makeText(
InterstitialAdActivity.this,
"광고 표시 실패: " + errorCode,
Toast.LENGTH_SHORT
).show();
}
});
}
private void loadInterstitialAd() {
Log.d(TAG, "전면 광고 로드 시작");
loadButton.setEnabled(false);
interstitialAd.load();
}
private void showInterstitialAd() {
if (interstitialAd != null && interstitialAd.isLoaded()) {
Log.d(TAG, "전면 광고 표시");
interstitialAd.show(this);
} else {
Log.w(TAG, "광고가 아직 로드되지 않았습니다");
Toast.makeText(this, "광고가 준비되지 않았습니다", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (interstitialAd != null) {
interstitialAd.destroy();
interstitialAd = null;
}
}
}
문제 해결
onAdReceived가 호출되지 않음
onAdReceived가 호출되지 않음
- SDK가 초기화되었는지 확인
- 유닛 ID가 올바른지 확인
- 네트워크 연결 상태 확인
- AndroidManifest.xml에 인터넷 권한이 설정되어 있는지 확인
onAdFailedToReceive가 호출됨
onAdFailedToReceive가 호출됨
- 에러 코드를 확인하여 원인 파악
ERROR_CODE_AD_NO_FILL: 광고 인벤토리 부족, 나중에 재시도ERROR_CODE_NETWORK: 네트워크 연결 확인ERROR_CODE_INVALID_UNIT: 유닛 ID 확인
show() 호출 후 아무 일도 일어나지 않음
show() 호출 후 아무 일도 일어나지 않음
onAdReceived콜백 이후에show()를 호출했는지 확인isLoaded프로퍼티가true인지 확인- Activity가 유효한지 확인
- 다른 전면 광고가 이미 표시 중이지 않은지 확인
메모리 누수 경고
메모리 누수 경고
onDestroy()에서destroy()메서드 호출 확인- Context 참조가 WeakReference로 관리되는지 확인
- 리스너를 null로 설정하는지 확인
백필 광고
백필 광고가 활성화된 경우, 직광고가 없을 때 자동으로 백필 광고가 로드됩니다.isBackfilled 프로퍼티로 백필 광고 여부를 확인할 수 있습니다.
interstitialAd.interstitialAdListener = object : AdropInterstitialAdListener {
override fun onAdReceived(ad: AdropInterstitialAd) {
if (ad.isBackfilled) {
println("백필 광고가 로드되었습니다")
} else {
println("직광고가 로드되었습니다")
}
}
override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
when (errorCode) {
AdropErrorCode.ERROR_CODE_AD_NO_FILL -> {
println("직광고 없음, 백필 광고 요청 중...")
}
AdropErrorCode.ERROR_CODE_AD_BACKFILL_NO_FILL -> {
println("백필 광고도 없음")
}
else -> {
println("광고 로드 실패: $errorCode")
}
}
}
}
interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
@Override
public void onAdReceived(AdropInterstitialAd ad) {
if (ad.isBackfilled()) {
System.out.println("백필 광고가 로드되었습니다");
} else {
System.out.println("직광고가 로드되었습니다");
}
}
@Override
public void onAdFailedToReceive(AdropInterstitialAd ad, AdropErrorCode errorCode) {
if (errorCode == AdropErrorCode.ERROR_CODE_AD_NO_FILL) {
System.out.println("직광고 없음, 백필 광고 요청 중...");
} else if (errorCode == AdropErrorCode.ERROR_CODE_AD_BACKFILL_NO_FILL) {
System.out.println("백필 광고도 없음");
} else {
System.out.println("광고 로드 실패: " + errorCode);
}
}
});
백필 광고를 사용하려면
io.adrop:adrop-ads-backfill 의존성을 추가해야 합니다. 시작하기를 참고하세요.다음 단계
보상형 광고
보상형 광고로 사용자 인게이지먼트 향상
배너 광고
배너 광고 구현하기
타겟팅 설정
사용자 속성 및 문맥 타겟팅
레퍼런스
API 레퍼런스 문서