개요
팝업 광고(Popup Ad)는 특정 순간에 화면에 나타나는 광고 포맷입니다. 앱 실행 시, 콘텐츠 로드 완료 시, 특정 이벤트 발생 시 등 원하는 타이밍에 표시할 수 있으며, 사용자가 닫기 버튼을 누르거나 “오늘 하루 보지 않기”를 선택하여 종료할 수 있습니다.특징
- 화면 중앙 또는 하단에 표시되는 팝업 형태
- 이미지 및 동영상 광고 지원
- 닫기, 딤(배경) 클릭, “오늘 하루 보지 않기” 옵션 제공
- 배경색, 텍스트 색상 등 커스터마이징 가능
- 비침투적이면서도 효과적인 광고 경험
개발 환경에서는 테스트 유닛 ID를 사용하세요. 테스트 유닛 ID 섹션을 참고하세요.
구현 단계
팝업 광고는 다음 4단계로 구현합니다:- 초기화 - AdropPopupAd 인스턴스 생성
- 리스너 설정 - 광고 및 닫기 이벤트 수신을 위한 리스너 설정
- 광고 로드 - 광고 요청 및 수신
- 광고 표시 - 화면에 광고 표시
기본 구현
기본 사용법
import io.adrop.ads.popupAd.AdropPopupAd
import io.adrop.ads.popupAd.AdropPopupAdListener
import io.adrop.ads.popupAd.AdropPopupAdCloseListener
import io.adrop.ads.model.AdropErrorCode
class MainActivity : AppCompatActivity() {
private var popupAd: AdropPopupAd? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 팝업 광고 로드
loadPopupAd()
}
// 1. 광고 초기화 및 로드
private fun loadPopupAd() {
popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")
popupAd?.popupAdListener = popupAdListener
popupAd?.closeListener = popupCloseListener
popupAd?.load()
}
// 2. 광고 표시
private fun showPopupAd() {
popupAd?.let { ad ->
if (ad.isLoaded) {
ad.show(this)
}
}
}
override fun onDestroy() {
super.onDestroy()
popupAd?.destroy()
}
}
import io.adrop.ads.popupAd.AdropPopupAd;
import io.adrop.ads.popupAd.AdropPopupAdListener;
import io.adrop.ads.popupAd.AdropPopupAdCloseListener;
import io.adrop.ads.model.AdropErrorCode;
public class MainActivity extends AppCompatActivity {
private AdropPopupAd popupAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 팝업 광고 로드
loadPopupAd();
}
// 1. 광고 초기화 및 로드
private void loadPopupAd() {
popupAd = new AdropPopupAd(this, "YOUR_POPUP_UNIT_ID");
popupAd.setPopupAdListener(popupAdListener);
popupAd.setCloseListener(popupCloseListener);
popupAd.load();
}
// 2. 광고 표시
private void showPopupAd() {
if (popupAd != null && popupAd.isLoaded()) {
popupAd.show(this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (popupAd != null) {
popupAd.destroy();
}
}
}
리스너 구현
// 광고 리스너 구현
private val popupAdListener = object : AdropPopupAdListener {
// 광고 수신 성공 (필수)
override fun onAdReceived(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 수신 완료")
// 광고가 준비되면 표시
showPopupAd()
}
// 광고 수신 실패 (필수)
override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
Log.d("Adrop", "팝업 광고 수신 실패: $errorCode")
}
// 광고 노출 (선택)
override fun onAdImpression(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 노출")
}
// 광고 클릭 (선택)
override fun onAdClicked(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 클릭")
}
// 팝업 광고가 표시되기 직전 (선택)
override fun onAdWillPresentFullScreen(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 표시 직전")
}
// 팝업 광고가 표시된 직후 (선택)
override fun onAdDidPresentFullScreen(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 표시 완료")
}
// 팝업 광고가 닫히기 직전 (선택)
override fun onAdWillDismissFullScreen(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 닫히기 직전")
}
// 팝업 광고가 닫힌 직후 (선택)
override fun onAdDidDismissFullScreen(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 닫힘")
// 다음 광고를 미리 로드
loadPopupAd()
}
// 팝업 광고 표시 실패 (선택)
override fun onAdFailedToShowFullScreen(ad: AdropPopupAd, errorCode: AdropErrorCode) {
Log.d("Adrop", "팝업 광고 표시 실패: $errorCode")
}
// 동영상 재생 시작 (선택)
override fun onAdVideoStart(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 동영상 재생 시작")
}
// 동영상 재생 종료 (선택)
override fun onAdVideoEnd(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 동영상 재생 종료")
}
}
// 닫기 리스너 구현
private val popupCloseListener = object : AdropPopupAdCloseListener {
// 닫기 버튼 클릭 (선택)
override fun onClosed(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 닫기 버튼 클릭")
}
// 딤(배경) 클릭 (선택)
override fun onDimClicked(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 딤 영역 클릭")
}
// "오늘 하루 보지 않기" 클릭 (선택)
override fun onTodayOffClicked(ad: AdropPopupAd) {
Log.d("Adrop", "오늘 하루 보지 않기 선택")
// 오늘 날짜를 저장하여 다음 표시를 제어
val prefs = getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE)
prefs.edit().putLong("last_popup_hidden_date", System.currentTimeMillis()).apply()
}
}
// 광고 리스너 구현
private final AdropPopupAdListener popupAdListener = new AdropPopupAdListener() {
// 광고 수신 성공 (필수)
@Override
public void onAdReceived(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 수신 완료");
// 광고가 준비되면 표시
showPopupAd();
}
// 광고 수신 실패 (필수)
@Override
public void onAdFailedToReceive(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
Log.d("Adrop", "팝업 광고 수신 실패: " + errorCode);
}
// 광고 노출 (선택)
@Override
public void onAdImpression(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 노출");
}
// 광고 클릭 (선택)
@Override
public void onAdClicked(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 클릭");
}
// 팝업 광고가 표시되기 직전 (선택)
@Override
public void onAdWillPresentFullScreen(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 표시 직전");
}
// 팝업 광고가 표시된 직후 (선택)
@Override
public void onAdDidPresentFullScreen(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 표시 완료");
}
// 팝업 광고가 닫히기 직전 (선택)
@Override
public void onAdWillDismissFullScreen(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 닫히기 직전");
}
// 팝업 광고가 닫힌 직후 (선택)
@Override
public void onAdDidDismissFullScreen(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 닫힘");
// 다음 광고를 미리 로드
loadPopupAd();
}
// 팝업 광고 표시 실패 (선택)
@Override
public void onAdFailedToShowFullScreen(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
Log.d("Adrop", "팝업 광고 표시 실패: " + errorCode);
}
// 동영상 재생 시작 (선택)
@Override
public void onAdVideoStart(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 동영상 재생 시작");
}
// 동영상 재생 종료 (선택)
@Override
public void onAdVideoEnd(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 동영상 재생 종료");
}
};
// 닫기 리스너 구현
private final AdropPopupAdCloseListener popupCloseListener = new AdropPopupAdCloseListener() {
// 닫기 버튼 클릭 (선택)
@Override
public void onClosed(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 닫기 버튼 클릭");
}
// 딤(배경) 클릭 (선택)
@Override
public void onDimClicked(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 딤 영역 클릭");
}
// "오늘 하루 보지 않기" 클릭 (선택)
@Override
public void onTodayOffClicked(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "오늘 하루 보지 않기 선택");
// 오늘 날짜를 저장하여 다음 표시를 제어
SharedPreferences prefs = getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE);
prefs.edit().putLong("last_popup_hidden_date", System.currentTimeMillis()).apply();
}
};
커스터마이징
팝업 광고의 외형을 커스터마이징할 수 있습니다.배경색 및 텍스트 색상 설정
private fun loadPopupAd() {
popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")
popupAd?.popupAdListener = popupAdListener
popupAd?.closeListener = popupCloseListener
// 배경색 설정 (딤 영역)
popupAd?.backgroundColor = Color.parseColor("#CC000000")
// "오늘 하루 보지 않기" 텍스트 색상
popupAd?.hideForTodayTextColor = Color.WHITE
// 닫기 버튼 텍스트 색상
popupAd?.closeTextColor = Color.WHITE
// CTA 버튼 텍스트 색상
popupAd?.ctaTextColor = Color.BLUE
popupAd?.load()
}
private void loadPopupAd() {
popupAd = new AdropPopupAd(this, "YOUR_POPUP_UNIT_ID");
popupAd.setPopupAdListener(popupAdListener);
popupAd.setCloseListener(popupCloseListener);
// 배경색 설정 (딤 영역)
popupAd.setBackgroundColor(Color.parseColor("#CC000000"));
// "오늘 하루 보지 않기" 텍스트 색상
popupAd.setHideForTodayTextColor(Color.WHITE);
// 닫기 버튼 텍스트 색상
popupAd.setCloseTextColor(Color.WHITE);
// CTA 버튼 텍스트 색상
popupAd.setCtaTextColor(Color.BLUE);
popupAd.load();
}
커스터마이징 옵션
| 속성 | 타입 | 설명 | 기본값 |
|---|---|---|---|
backgroundColor | Int? | 팝업 배경(딤) 색상 | 검은색 (투명도 0.8) |
hideForTodayTextColor | Int? | ”오늘 하루 보지 않기” 텍스트 색상 | 흰색 |
closeTextColor | Int? | 닫기 버튼 텍스트 색상 | 흰색 |
ctaTextColor | Int? | CTA 버튼 텍스트 색상 | 시스템 기본값 |
커스텀 클릭 처리
광고 클릭 시 기본 브라우저 열기 대신 커스텀 처리를 하려면useCustomClick 속성을 사용하세요.
private fun loadPopupAd() {
popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")
// 커스텀 클릭 처리 활성화
popupAd?.useCustomClick = true
popupAd?.popupAdListener = object : AdropPopupAdListener {
override fun onAdReceived(ad: AdropPopupAd) {
showPopupAd()
}
override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
Log.d("Adrop", "광고 수신 실패: $errorCode")
}
override fun onAdClicked(ad: AdropPopupAd) {
// 커스텀 클릭 처리
Log.d("Adrop", "광고 클릭됨: ${ad.destinationURL}")
// 원하는 URL로 열기
popupAd?.open("https://your-custom-url.com")
// 또는 In-App 브라우저로 열기
// openInAppBrowser(ad.destinationURL)
}
}
popupAd?.load()
}
private void loadPopupAd() {
popupAd = new AdropPopupAd(this, "YOUR_POPUP_UNIT_ID");
// 커스텀 클릭 처리 활성화
popupAd.setUseCustomClick(true);
popupAd.setPopupAdListener(new AdropPopupAdListener() {
@Override
public void onAdReceived(@NotNull AdropPopupAd ad) {
showPopupAd();
}
@Override
public void onAdFailedToReceive(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
Log.d("Adrop", "광고 수신 실패: " + errorCode);
}
@Override
public void onAdClicked(@NotNull AdropPopupAd ad) {
// 커스텀 클릭 처리
Log.d("Adrop", "광고 클릭됨: " + ad.getDestinationURL());
// 원하는 URL로 열기
popupAd.open("https://your-custom-url.com");
// 또는 In-App 브라우저로 열기
// openInAppBrowser(ad.getDestinationURL());
}
});
popupAd.load();
}
광고 속성
팝업 광고 객체에서 다음 속성들을 사용할 수 있습니다:String
광고 유닛 ID
Boolean
광고가 로드되었는지 여부
String
현재 표시 중인 광고 크리에이티브 ID
String
광고 클릭 시 이동할 URL
String
트랜잭션 ID (광고 노출 추적용)
String
캠페인 ID
리스너 메서드
AdropPopupAdListener (광고 이벤트)
필수 메서드
(AdropPopupAd) -> Unit
광고 수신 성공 시 호출됩니다. 이 시점에서
show()를 호출하여 광고를 표시할 수 있습니다.(AdropPopupAd, AdropErrorCode) -> Unit
광고 수신 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
선택 메서드
(AdropPopupAd) -> Unit
광고 노출이 기록되었을 때 호출됩니다.
(AdropPopupAd) -> Unit
사용자가 광고를 클릭했을 때 호출됩니다.
(AdropPopupAd) -> Unit
팝업 광고가 표시되기 직전에 호출됩니다.
(AdropPopupAd) -> Unit
팝업 광고가 화면에 표시된 직후 호출됩니다.
(AdropPopupAd) -> Unit
팝업 광고가 닫히기 직전에 호출됩니다.
(AdropPopupAd) -> Unit
팝업 광고가 닫힌 직후 호출됩니다. 다음 광고를 미리 로드하기 좋은 시점입니다.
(AdropPopupAd, AdropErrorCode) -> Unit
광고 표시 실패 시 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
(AdropPopupAd) -> Unit
동영상 팝업 광고에서 동영상 재생이 시작되었을 때 호출됩니다.
(AdropPopupAd) -> Unit
동영상 팝업 광고에서 동영상 재생이 종료되었을 때 호출됩니다.
AdropPopupAdCloseListener (닫기 이벤트)
모든 메서드가 선택사항입니다.(AdropPopupAd) -> Unit
사용자가 닫기 버튼을 클릭했을 때 호출됩니다.
(AdropPopupAd) -> Unit
사용자가 팝업 외부(딤 영역)를 클릭했을 때 호출됩니다.
(AdropPopupAd) -> Unit
사용자가 “오늘 하루 보지 않기”를 선택했을 때 호출됩니다. 이 콜백에서 날짜를 저장하여 하루 동안 광고를 표시하지 않도록 구현할 수 있습니다.
”오늘 하루 보지 않기” 구현
사용자가 “오늘 하루 보지 않기”를 선택했을 때 적절히 처리하는 방법입니다.SharedPreferences를 이용한 구현
class PopupAdManager(private val context: Context) {
private val prefs = context.getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE)
private val todayOffKey = "popup_ad_today_off_date"
private var popupAd: AdropPopupAd? = null
// 오늘 광고를 표시할 수 있는지 확인
fun canShowAdToday(): Boolean {
val lastHiddenDate = prefs.getLong(todayOffKey, 0L)
if (lastHiddenDate == 0L) return true
val calendar = Calendar.getInstance()
calendar.timeInMillis = lastHiddenDate
val hiddenDay = calendar.get(Calendar.DAY_OF_YEAR)
val hiddenYear = calendar.get(Calendar.YEAR)
calendar.timeInMillis = System.currentTimeMillis()
val currentDay = calendar.get(Calendar.DAY_OF_YEAR)
val currentYear = calendar.get(Calendar.YEAR)
// 저장된 날짜가 오늘이 아니면 표시 가능
return hiddenDay != currentDay || hiddenYear != currentYear
}
// 광고 로드 및 표시
fun loadAndShowAd(activity: Activity, unitId: String) {
if (!canShowAdToday()) {
Log.d("Adrop", "오늘은 광고를 표시하지 않습니다")
return
}
popupAd?.destroy()
popupAd = AdropPopupAd(activity, unitId)
popupAd?.popupAdListener = popupAdListener
popupAd?.closeListener = popupCloseListener
popupAd?.load()
}
private val popupAdListener = object : AdropPopupAdListener {
override fun onAdReceived(ad: AdropPopupAd) {
// 광고 수신 후 자동 표시
if (context is Activity) {
ad.show(context)
}
}
override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
Log.d("Adrop", "광고 수신 실패: $errorCode")
}
}
private val popupCloseListener = object : AdropPopupAdCloseListener {
override fun onTodayOffClicked(ad: AdropPopupAd) {
// 오늘 날짜를 저장
prefs.edit().putLong(todayOffKey, System.currentTimeMillis()).apply()
Log.d("Adrop", "오늘 하루 팝업 광고를 표시하지 않습니다")
}
}
fun destroy() {
popupAd?.destroy()
popupAd = null
}
}
public class PopupAdManager {
private Context context;
private SharedPreferences prefs;
private static final String PREFS_NAME = "adrop_prefs";
private static final String TODAY_OFF_KEY = "popup_ad_today_off_date";
private AdropPopupAd popupAd;
public PopupAdManager(Context context) {
this.context = context;
this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
// 오늘 광고를 표시할 수 있는지 확인
public boolean canShowAdToday() {
long lastHiddenDate = prefs.getLong(TODAY_OFF_KEY, 0L);
if (lastHiddenDate == 0L) return true;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(lastHiddenDate);
int hiddenDay = calendar.get(Calendar.DAY_OF_YEAR);
int hiddenYear = calendar.get(Calendar.YEAR);
calendar.setTimeInMillis(System.currentTimeMillis());
int currentDay = calendar.get(Calendar.DAY_OF_YEAR);
int currentYear = calendar.get(Calendar.YEAR);
// 저장된 날짜가 오늘이 아니면 표시 가능
return hiddenDay != currentDay || hiddenYear != currentYear;
}
// 광고 로드 및 표시
public void loadAndShowAd(Activity activity, String unitId) {
if (!canShowAdToday()) {
Log.d("Adrop", "오늘은 광고를 표시하지 않습니다");
return;
}
if (popupAd != null) {
popupAd.destroy();
}
popupAd = new AdropPopupAd(activity, unitId);
popupAd.setPopupAdListener(popupAdListener);
popupAd.setCloseListener(popupCloseListener);
popupAd.load();
}
private final AdropPopupAdListener popupAdListener = new AdropPopupAdListener() {
@Override
public void onAdReceived(@NotNull AdropPopupAd ad) {
// 광고 수신 후 자동 표시
if (context instanceof Activity) {
ad.show((Activity) context);
}
}
@Override
public void onAdFailedToReceive(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
Log.d("Adrop", "광고 수신 실패: " + errorCode);
}
};
private final AdropPopupAdCloseListener popupCloseListener = new AdropPopupAdCloseListener() {
@Override
public void onTodayOffClicked(@NotNull AdropPopupAd ad) {
// 오늘 날짜를 저장
prefs.edit().putLong(TODAY_OFF_KEY, System.currentTimeMillis()).apply();
Log.d("Adrop", "오늘 하루 팝업 광고를 표시하지 않습니다");
}
};
public void destroy() {
if (popupAd != null) {
popupAd.destroy();
popupAd = null;
}
}
}
사용 예시
class MainActivity : AppCompatActivity() {
private lateinit var popupAdManager: PopupAdManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
popupAdManager = PopupAdManager(this)
// 앱 시작 시 팝업 광고 표시
popupAdManager.loadAndShowAd(this, "YOUR_POPUP_UNIT_ID")
}
override fun onDestroy() {
super.onDestroy()
popupAdManager.destroy()
}
}
public class MainActivity extends AppCompatActivity {
private PopupAdManager popupAdManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
popupAdManager = new PopupAdManager(this);
// 앱 시작 시 팝업 광고 표시
popupAdManager.loadAndShowAd(this, "YOUR_POPUP_UNIT_ID");
}
@Override
protected void onDestroy() {
super.onDestroy();
popupAdManager.destroy();
}
}
팝업 타입
팝업 광고는 두 가지 타입으로 제공됩니다:| 타입 | 설명 | 위치 |
|---|---|---|
POPUP_BOTTOM | 하단 팝업 | 화면 하단에서 올라오는 형태 |
POPUP_CENTER | 중앙 팝업 | 화면 중앙에 표시되는 형태 |
팝업 타입은 애드컨트롤 콘솔에서 광고 유닛 생성 시 설정됩니다. 코드에서 별도로 지정할 필요가 없습니다.
모범 사례
1. 적절한 표시 시점
팝업 광고는 다음 시점에 표시하는 것이 효과적입니다:// ✅ 좋은 예: 앱 시작 시
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loadAndShowPopupAd()
}
// ✅ 좋은 예: 콘텐츠 로드 완료 시
fun onContentLoaded() {
if (shouldShowPopupAd()) {
showPopupAd()
}
}
// ✅ 좋은 예: 특정 이벤트 완료 시
fun onAchievementUnlocked() {
showPopupAd()
}
// ❌ 나쁜 예: 사용자가 작업 중일 때
fun onUserTyping() {
showPopupAd() // 사용자 경험 저해
}
2. “오늘 하루 보지 않기” 존중
사용자가 “오늘 하루 보지 않기”를 선택했다면 반드시 준수하세요.fun shouldShowPopupAd(): Boolean {
// 오늘 하루 보지 않기 확인
if (!canShowAdToday()) {
return false
}
// 다른 조건 확인
return true
}
3. 빈도 제한
팝업 광고를 너무 자주 표시하지 마세요.class PopupAdFrequencyManager(private val context: Context) {
private val prefs = context.getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE)
private val lastShownKey = "popup_ad_last_shown"
private val minimumInterval = 3600000L // 1시간 (밀리초)
fun canShowAd(): Boolean {
// 오늘 하루 보지 않기 확인
if (!canShowAdToday()) {
return false
}
// 최소 시간 간격 확인
val lastShown = prefs.getLong(lastShownKey, 0L)
if (lastShown == 0L) return true
val currentTime = System.currentTimeMillis()
return currentTime - lastShown >= minimumInterval
}
fun recordAdShown() {
prefs.edit().putLong(lastShownKey, System.currentTimeMillis()).apply()
}
private fun canShowAdToday(): Boolean {
// 위의 "오늘 하루 보지 않기" 구현 참고
return true
}
}
public class PopupAdFrequencyManager {
private SharedPreferences prefs;
private static final String PREFS_NAME = "adrop_prefs";
private static final String LAST_SHOWN_KEY = "popup_ad_last_shown";
private static final long MINIMUM_INTERVAL = 3600000L; // 1시간 (밀리초)
public PopupAdFrequencyManager(Context context) {
this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
public boolean canShowAd() {
// 오늘 하루 보지 않기 확인
if (!canShowAdToday()) {
return false;
}
// 최소 시간 간격 확인
long lastShown = prefs.getLong(LAST_SHOWN_KEY, 0L);
if (lastShown == 0L) return true;
long currentTime = System.currentTimeMillis();
return currentTime - lastShown >= MINIMUM_INTERVAL;
}
public void recordAdShown() {
prefs.edit().putLong(LAST_SHOWN_KEY, System.currentTimeMillis()).apply();
}
private boolean canShowAdToday() {
// 위의 "오늘 하루 보지 않기" 구현 참고
return true;
}
}
4. 광고 미리 로드
사용자 경험을 위해 광고를 미리 로드하세요.class MainActivity : AppCompatActivity() {
private var popupAd: AdropPopupAd? = null
private var isAdReady = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 미리 로드
preloadPopupAd()
}
private fun preloadPopupAd() {
popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")
popupAd?.popupAdListener = object : AdropPopupAdListener {
override fun onAdReceived(ad: AdropPopupAd) {
isAdReady = true
}
override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
Log.d("Adrop", "광고 수신 실패: $errorCode")
}
}
popupAd?.load()
}
fun showPopupAdIfReady() {
if (isAdReady) {
popupAd?.show(this)
}
}
}
5. 가로 모드 처리
SDK 1.16.0부터는 팝업 광고가 가로 모드에서도 표시되며, 표시 중인 팝업은 앱과 함께 회전합니다. 이전 버전에서는 팝업 광고가 세로 모드에서만 표시되어, 가로 모드에서show()를 호출하면 onAdFailedToShowFullScreen이 ERROR_CODE_LANDSCAPE_UNSUPPORTED와 함께 호출됩니다.
이전 버전을 쓰는 앱이라면 세로 모드일 때만 광고를 표시하세요.
private val popupAdListener = object : AdropPopupAdListener {
override fun onAdReceived(ad: AdropPopupAd) {
// 세로 모드일 때만 표시
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
ad.show(this@MainActivity)
}
}
override fun onAdFailedToShowFullScreen(ad: AdropPopupAd, errorCode: AdropErrorCode) {
if (errorCode == AdropErrorCode.ERROR_CODE_LANDSCAPE_UNSUPPORTED) {
Log.d("Adrop", "팝업 광고는 세로 모드에서만 지원됩니다")
}
}
override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
Log.d("Adrop", "광고 수신 실패: $errorCode")
}
}
테스트 유닛 ID
개발 및 테스트 시 다음 테스트 유닛 ID를 사용하세요.| 광고 타입 | 테스트 유닛 ID |
|---|---|
| 팝업 (하단 이미지) | PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM |
| 팝업 (중앙 이미지) | PUBLIC_TEST_UNIT_ID_POPUP_CENTER |
| 팝업 비디오 (하단 16:9) | PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM_VIDEO_16_9 |
| 팝업 비디오 (하단 9:16) | PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM_VIDEO_9_16 |
| 팝업 비디오 (중앙 16:9) | PUBLIC_TEST_UNIT_ID_POPUP_CENTER_VIDEO_16_9 |
| 팝업 비디오 (중앙 9:16) | PUBLIC_TEST_UNIT_ID_POPUP_CENTER_VIDEO_9_16 |
테스트 광고 사용 예시
// 테스트 환경과 프로덕션 환경 분리
val popupUnitId = if (BuildConfig.DEBUG) {
"PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM"
} else {
"YOUR_PRODUCTION_UNIT_ID"
}
popupAd = AdropPopupAd(this, popupUnitId)
// 테스트 환경과 프로덕션 환경 분리
String popupUnitId;
if (BuildConfig.DEBUG) {
popupUnitId = "PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM";
} else {
popupUnitId = "YOUR_PRODUCTION_UNIT_ID";
}
popupAd = new AdropPopupAd(this, popupUnitId);
실제 배포 시에는 반드시 애드컨트롤 콘솔에서 생성한 실제 유닛 ID를 사용하세요.
완전한 예제
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import io.adrop.ads.model.AdropErrorCode
import io.adrop.ads.popupAd.AdropPopupAd
import io.adrop.ads.popupAd.AdropPopupAdCloseListener
import io.adrop.ads.popupAd.AdropPopupAdListener
class PopupAdActivity : AppCompatActivity() {
private var popupAd: AdropPopupAd? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_popup_ad)
// 버튼 클릭 시 광고 로드 및 표시
findViewById<Button>(R.id.btn_show_popup).setOnClickListener {
loadPopupAd()
}
}
private fun loadPopupAd() {
// 기존 광고 정리
popupAd?.destroy()
// 팝업 광고 생성
popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")
// 커스터마이징
popupAd?.apply {
backgroundColor = Color.parseColor("#CC000000")
hideForTodayTextColor = Color.WHITE
closeTextColor = Color.WHITE
ctaTextColor = Color.BLUE
useCustomClick = false
}
// 리스너 설정
popupAd?.popupAdListener = object : AdropPopupAdListener {
override fun onAdReceived(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 수신 완료")
showPopupAd()
}
override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
Log.d("Adrop", "팝업 광고 수신 실패: $errorCode")
}
override fun onAdImpression(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 노출")
Log.d("Adrop", "txId: ${ad.txId}, campaignId: ${ad.campaignId}")
}
override fun onAdClicked(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 클릭: ${ad.destinationURL}")
}
override fun onAdDidPresentFullScreen(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 표시됨")
}
override fun onAdDidDismissFullScreen(ad: AdropPopupAd) {
Log.d("Adrop", "팝업 광고 닫힘")
// 다음 광고 미리 로드
loadPopupAd()
}
override fun onAdFailedToShowFullScreen(ad: AdropPopupAd, errorCode: AdropErrorCode) {
Log.d("Adrop", "팝업 광고 표시 실패: $errorCode")
}
}
popupAd?.closeListener = object : AdropPopupAdCloseListener {
override fun onClosed(ad: AdropPopupAd) {
Log.d("Adrop", "닫기 버튼 클릭")
}
override fun onDimClicked(ad: AdropPopupAd) {
Log.d("Adrop", "딤 영역 클릭")
}
override fun onTodayOffClicked(ad: AdropPopupAd) {
Log.d("Adrop", "오늘 하루 보지 않기 선택")
saveHiddenDate()
}
}
// 광고 로드
popupAd?.load()
}
private fun showPopupAd() {
popupAd?.let { ad ->
if (ad.isLoaded) {
ad.show(this)
}
}
}
private fun saveHiddenDate() {
val prefs = getSharedPreferences("adrop_prefs", MODE_PRIVATE)
prefs.edit().putLong("last_popup_hidden_date", System.currentTimeMillis()).apply()
}
override fun onDestroy() {
super.onDestroy()
popupAd?.destroy()
}
}
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import io.adrop.ads.model.AdropErrorCode;
import io.adrop.ads.popupAd.AdropPopupAd;
import io.adrop.ads.popupAd.AdropPopupAdCloseListener;
import io.adrop.ads.popupAd.AdropPopupAdListener;
import org.jetbrains.annotations.NotNull;
public class PopupAdActivity extends AppCompatActivity {
private AdropPopupAd popupAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popup_ad);
// 버튼 클릭 시 광고 로드 및 표시
findViewById(R.id.btn_show_popup).setOnClickListener(v -> loadPopupAd());
}
private void loadPopupAd() {
// 기존 광고 정리
if (popupAd != null) {
popupAd.destroy();
}
// 팝업 광고 생성
popupAd = new AdropPopupAd(this, "YOUR_POPUP_UNIT_ID");
// 커스터마이징
popupAd.setBackgroundColor(Color.parseColor("#CC000000"));
popupAd.setHideForTodayTextColor(Color.WHITE);
popupAd.setCloseTextColor(Color.WHITE);
popupAd.setCtaTextColor(Color.BLUE);
popupAd.setUseCustomClick(false);
// 리스너 설정
popupAd.setPopupAdListener(new AdropPopupAdListener() {
@Override
public void onAdReceived(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 수신 완료");
showPopupAd();
}
@Override
public void onAdFailedToReceive(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
Log.d("Adrop", "팝업 광고 수신 실패: " + errorCode);
}
@Override
public void onAdImpression(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 노출");
Log.d("Adrop", "txId: " + ad.getTxId() + ", campaignId: " + ad.getCampaignId());
}
@Override
public void onAdClicked(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 클릭: " + ad.getDestinationURL());
}
@Override
public void onAdDidPresentFullScreen(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 표시됨");
}
@Override
public void onAdDidDismissFullScreen(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "팝업 광고 닫힘");
// 다음 광고 미리 로드
loadPopupAd();
}
@Override
public void onAdFailedToShowFullScreen(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
Log.d("Adrop", "팝업 광고 표시 실패: " + errorCode);
}
});
popupAd.setCloseListener(new AdropPopupAdCloseListener() {
@Override
public void onClosed(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "닫기 버튼 클릭");
}
@Override
public void onDimClicked(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "딤 영역 클릭");
}
@Override
public void onTodayOffClicked(@NotNull AdropPopupAd ad) {
Log.d("Adrop", "오늘 하루 보지 않기 선택");
saveHiddenDate();
}
});
// 광고 로드
popupAd.load();
}
private void showPopupAd() {
if (popupAd != null && popupAd.isLoaded()) {
popupAd.show(this);
}
}
private void saveHiddenDate() {
getSharedPreferences("adrop_prefs", MODE_PRIVATE)
.edit()
.putLong("last_popup_hidden_date", System.currentTimeMillis())
.apply();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (popupAd != null) {
popupAd.destroy();
}
}
}
문제 해결
광고가 표시되지 않음
onAdReceived가 호출되지 않음
onAdReceived가 호출되지 않음
- SDK가 초기화되었는지 확인
- 유닛 ID가 올바른지 확인
- 네트워크 연결 상태 확인
- Adrop SDK 초기화 시
production설정 확인
onAdFailedToReceive가 호출됨
onAdFailedToReceive가 호출됨
- 에러 코드를 확인하여 원인 파악
- 테스트 환경에서는 테스트 유닛 ID 사용
- 광고 인벤토리 부족 시 나중에 재시도
ERROR_CODE_AD_HIDE_FOR_TODAY: “오늘 하루 보지 않기”가 활성화된 상태
show() 호출 후 아무 일도 일어나지 않음
show() 호출 후 아무 일도 일어나지 않음
onAdReceived콜백 이후에show()를 호출했는지 확인- Activity가 유효한 상태인지 확인
isLoaded속성을 확인하여 광고가 로드되었는지 확인- SDK 1.16.0 미만이라면 세로 모드인지 확인 (가로 모드는 지원되지 않음)
가로 모드에서 광고가 표시되지 않음
가로 모드에서 광고가 표시되지 않음
SDK 1.16.0 미만에서는 팝업 광고가 세로 모드에서만 지원됩니다. 가로 모드에서
show()를 호출하면 onAdFailedToShowFullScreen이 ERROR_CODE_LANDSCAPE_UNSUPPORTED 에러 코드와 함께 호출됩니다. 가로 모드에서도 팝업 광고를 표시하려면 1.16.0 이상으로 업데이트하세요.”오늘 하루 보지 않기”가 작동하지 않음
// 날짜 비교 로직 확인
fun isToday(timestamp: Long): Boolean {
val calendar = Calendar.getInstance()
val today = calendar.apply {
timeInMillis = System.currentTimeMillis()
}
val targetDay = Calendar.getInstance().apply {
timeInMillis = timestamp
}
return today.get(Calendar.YEAR) == targetDay.get(Calendar.YEAR) &&
today.get(Calendar.DAY_OF_YEAR) == targetDay.get(Calendar.DAY_OF_YEAR)
}
// 사용
fun canShowAdToday(): Boolean {
val prefs = getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE)
val lastHiddenDate = prefs.getLong("last_popup_hidden_date", 0L)
return lastHiddenDate == 0L || !isToday(lastHiddenDate)
}
관련 문서
시작하기
SDK 설치 및 초기화
전면 광고
전면 광고 구현하기
보상형 광고
보상형 광고 구현하기
배너 광고
배너 광고 구현하기