적응형 스티키 배너
앱 화면의 상단 또는 하단에 배치되어 자동으로 업데이트되는 작은 광고입니다. 주요 앱 콘텐츠와 겹치지 않으며 게임 앱에서 자주 사용됩니다.
적응형 스티키 배너는 각 장치에서 광고 크기를 최적화하여 최대 효율성을 제공합니다. 이 광고 유형은 개발자가 허용 가능한 최대 광고 너비를 설정할 수 있게 하지만, 최적의 광고 크기는 여전히 자동으로 결정됩니다. 적응형 스티키 배너의 높이는 화면 높이의 15%를 초과해서는 안 됩니다.
표시 예

이 가이드는 Android 앱에 적응형 스티키 배너를 통합하는 과정을 다룹니다. 코드 샘플과 지침 외에도 형식별 권장 사항 및 추가 자료에 대한 링크가 포함되어 있습니다.
사전 준비
- 빠른 시작에 설명된 SDK 통합 단계를 수행하세요.
- 광고 SDK를 미리 초기화하세요.
- 최신 Yandex Mobile Ads SDK 버전을 사용하고 있는지 확인하세요. 중재를 사용하는 경우, 최신 통합 빌드 버전을 실행하고 있는지도 확인하세요.
실행
적응형 스티키 배너 통합을 위한 주요 단계:
- 배너 광고를 표시하기 위한 보기를 생성 및 구성합니다.
- 콜백 리스너를 등록합니다.
- 광고를 로드합니다.
- Adfox를 사용하는 경우 추가 설정을 전달합니다.
적응형 스티키 배너 통합의 특징
-
Yandex Mobile Ads SDK 메서드에 대한 모든 호출은 메인 스레드에서 이루어져야 합니다.
-
onAdFailedToLoad()
콜백이 오류를 반환하면 새로운 광고를 다시 로드하려고 시도하지 마세요. 다른 옵션이 없는 경우, 광고 로드 재시도 횟수를 제한하세요. 이렇게 하면 제한이 있는 경우 지속적인 실패 요청 및 연결 문제를 방지할 수 있습니다. -
적응형 스티키 배너는 사용 가능한 전체 너비를 활용할 때 가장 잘 작동합니다. 대부분의 경우에는 장치 화면의 전체 너비에 해당합니다. 앱에 설정된 패딩 매개변수와 디스플레이의 안전 영역을 고려하세요.
-
광고의 크기를 가져오려면 컨텍스트와 광고 컨테이너의 사용 가능한 너비를 인수로 수용하는
BannerAdSize.stickySize(context, adWidth)
메서드를 사용하세요. -
중재가 활성화된 경우, 초기화가 완료될 때까지 기다린 후에 스티키 배너의 크기를 계산하는 것을 적극 권장합니다. 초기화가 완료되기 전까지는 임시 크기만 제공되며, 정확한 설정을 확보한 후에는 변경될 수 있습니다.
-
BannerAdSize.stickySize(context, adWidth)
메서드를 사용하여 계산된BannerAdSize
객체 내에 포함된 광고 너비 및 높이 값은 동일한 장치 내에 일관되게 적용됩니다. 특정 장치에서 앱의 레이아웃을 테스트할 때 해당 장치의 광고 크기가 동일하게 유지됨을 확신할 수 있습니다. -
적응형 스티키 배너의 높이는 화면 높이의 15%를 초과하지 않으며 50dp보다 작을 수 없습니다.
앱 레이아웃에 광고 보기 추가
배너 광고를 표시하려면 앱 레이아웃에 BannerAdView를 추가하세요. 프로그래매틱 방식으로, 또는 XML 파일을 사용하여 수행할 수 있습니다.
앱 화면 레이아웃에 BannerAdView 추가 예시:
# activity.xml
...
<com.yandex.mobile.ads.banner.BannerAdView
android:id="@+id/ad_container_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" />
...
BannerAdView 인스턴스를 프로그래매틱 방식으로 생성할 수도 있습니다.
val bannerAd = BannerAdView(this)
final BannerAdView bannerAd = new BannerAdView(this);
광고 로드 및 렌더링
앱 화면에 BannerAdView를 생성하고 추가하면 광고를 로드해야 합니다. 적응형 스티키 배너를 로드하기 전에 각 장치의 광고 크기를 계산합니다.
이 작업은 SDK API 메서드( BannerAdSize.stickySize(context, adWidth)
)를 통해 자동으로 진행됩니다.
컨텍스트와 최대 허용 광고 컨테이너 너비를 인수로 전달합니다. 장치 화면의 전체 너비 또는 상위 컨테이너의 너비를 사용하는 것이 좋습니다. 앱에 설정된 패딩 매개변수와 디스플레이의 안전 영역을 고려하세요.
private val adSize: BannerAdSize
get() {
// 광고 컨테이너의 패딩을 고려하여 광고의 너비를 계산합니다.
var adWidthPixels = binding.adContainerView.width
if (adWidthPixels == 0) {
// 광고가 배치되지 않은 경우 기본적으로 전체 화면 너비로 설정합니다
adWidthPixels = resources.displayMetrics.widthPixels
}
val adWidth = (adWidthPixels / resources.displayMetrics.density).roundToInt()
return BannerAdSize.stickySize(this, adWidth)
}
@NonNull
private BannerAdSize getAdSize() {
final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
// 광고 컨테이너의 패딩을 고려하여 광고의 너비를 계산합니다.
int adWidthPixels = mBinding.adContainerView.getWidth();
if (adWidthPixels == 0) {
// 광고가 배치되지 않은 경우 기본적으로 전체 화면 너비로 설정합니다
adWidthPixels = displayMetrics.widthPixels;
}
final int adWidth = Math.round(adWidthPixels / displayMetrics.density);
return BannerAdSize.stickySize(this, adWidth);
}
광고를 로드하려면 Yandex Advertising Network 인터페이스에서 확보한 Activity 컨텍스트와 광고 단위 ID가 필요합니다(adUnitId).
광고가 로드되거나 로드에 실패할 때 알림을 활성화하고 적응형 스티키 배너의 수명 주기 이벤트를 추적하려면 BannerAdView 클래스 인스턴스에 대한 BannerAdEventListener
콜백 리스너를 설정하세요.
AdRequest.Builder()
클래스로 광고 요청 매개 변수를 확장하여 사용자의 관심사, 페이지 컨텍스트, 위치 및 기타 추가 데이터에 대한 정보를 광고 요청에 포함할 수 있습니다. 광고 요청에 추가된 컨텍스트는 광고 품질을 크게 향상할 수 있습니다. 자세히 알아보려면 광고 타겟팅을 참고하세요.
아래 예시는 적응형 스티키 배너를 로드하는 방법을 보여줍니다. 로드되면 배너가 자동으로 표시됩니다.
class StickyBannerAdActivity : AppCompatActivity(R.layout.activity_sticky_banner_ad) {
private var bannerAd: BannerAdView? = null
private lateinit var binding: ActivityStickyBannerAdBinding
private val adSize: BannerAdSize
get() {
// 광고 컨테이너의 패딩을 고려하여 광고의 너비를 계산합니다.
var adWidthPixels = binding.adContainerView.width
if (adWidthPixels == 0) {
// 광고가 배치되지 않은 경우 기본적으로 전체 화면 너비로 설정합니다
adWidthPixels = resources.displayMetrics.widthPixels
}
val adWidth = (adWidthPixels / resources.displayMetrics.density).roundToInt()
return BannerAdSize.stickySize(this, adWidth)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityStickyBannerAdBinding.inflate(layoutInflater)
setContentView(binding.root)
// adContainerView 크기를 기준으로 배너를 로드하기 때문에
// 이 뷰가 배치될 때까지 기다려야 너비를 얻을 수 있습니다
binding.adContainerView.viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
binding.adContainerView.viewTreeObserver.removeOnGlobalLayoutListener(this);
bannerAd = loadBannerAd(adSize)
}
})
}
private fun loadBannerAd(adSize: BannerAdSize): BannerAdView {
return binding.banner.apply {
setAdSize(adSize)
setAdUnitId("your-ad-unit-id")
setBannerAdEventListener(object : BannerAdEventListener {
override fun onAdLoaded() {
// 활동이 훼손된 후에 이 콜백이 발생하면
// destroy를 호출하고 반환해야 하며 그렇지 않으면 메모리가 누출될 수 있습니다.
// `isDestroyed`은(는) Activity의 메서드입니다.
if (isDestroyed) {
bannerAd?.destroy()
return
}
}
override fun onAdFailedToLoad(adRequestError: AdRequestError) {
// AdRequestError로 광고를 로드하는 데 실패했습니다.
// onAdFailedToLoad() 메서드에서 새 광고를 로드하려는 시도는 권장되지 않습니다.
}
override fun onAdClicked() {
// 광고에 대한 클릭이 기록될 때 호출됩니다.
}
override fun onLeftApplication() {
// 사용자가 광고를 클릭한 후 애플리케이션을 종료하려고 할 때(예: 브라우저로 이동) 호출됩니다.
}
override fun onReturnedToApplication() {
// 사용자가 클릭한 후 애플리케이션으로 돌아왔을 때 호출됩니다.
}
override fun onImpression(impressionData: ImpressionData?) {
// 광고에 대한 노출이 기록될 때 호출됩니다.
}
})
loadAd(
AdRequest.Builder()
// 여기서 AdRequest.Builder 클래스의 메서드를 사용하여 개별 옵션 설정을 지정할 수 있습니다.
.build()
)
}
}
}
public class StickyBannerAdActivity extends AppCompatActivity {
@Nullable
private BannerAdView mBannerAd = null;
private ActivityStickyBannerAdBinding mBinding;
public StickyBannerAdActivity() {
super(R.layout.activity_sticky_banner_ad);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = ActivityStickyBannerAdBinding.inflate(getLayoutInflater());
setContentView(mBinding.getRoot());
// adContainerView 크기를 기준으로 배너를 로드하기 때문에
// 이 뷰가 배치될 때까지 기다려야 너비를 얻을 수 있습니다
mBinding.adContainerView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mBinding.adContainerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
mBannerAd = loadBannerAd(getAdSize());
}
}
);
}
@NonNull
private BannerAdSize getAdSize() {
final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
// 광고 컨테이너의 패딩을 고려하여 광고의 너비를 계산합니다.
int adWidthPixels = mBinding.adContainerView.getWidth();
if (adWidthPixels == 0) {
// 광고가 배치되지 않은 경우 기본적으로 전체 화면 너비로 설정합니다
adWidthPixels = displayMetrics.widthPixels;
}
final int adWidth = Math.round(adWidthPixels / displayMetrics.density);
return BannerAdSize.stickySize(this, adWidth);
}
@NonNull
private BannerAdView loadBannerAd(@NonNull final BannerAdSize adSize) {
final BannerAdView bannerAd = mBinding.banner;
bannerAd.setAdSize(adSize);
bannerAd.setAdUnitId("your-ad-unit-id");
bannerAd.setBannerAdEventListener(new BannerAdEventListener() {
@Override
public void onAdLoaded() {
// 활동이 훼손된 후에 이 콜백이 발생하면
// destroy를 호출하고 반환해야 하며 그렇지 않으면 메모리가 누출될 수 있습니다.
// `isDestroyed`은(는) Activity의 메서드입니다.
if (isDestroyed() && mBannerAd != null) {
mBannerAd.destroy();
}
}
@Override
public void onAdFailedToLoad(@NonNull final AdRequestError adRequestError) {
// AdRequestError로 광고를 로드하는 데 실패했습니다.
// onAdFailedToLoad() 메서드에서 새 광고를 로드하려는 시도는 권장되지 않습니다.
}
@Override
public void onAdClicked() {
// 광고에 대한 클릭이 기록될 때 호출됩니다.
}
@Override
public void onLeftApplication() {
// 사용자가 광고를 클릭한 후 애플리케이션을 종료하려고 할 때(예: 브라우저로 이동) 호출됩니다.
}
@Override
public void onReturnedToApplication() {
// 사용자가 클릭한 후 애플리케이션으로 돌아왔을 때 호출됩니다.
}
@Override
public void onImpression(@Nullable ImpressionData impressionData) {
// 광고에 대한 노출이 기록될 때 호출됩니다.
}
});
final AdRequest adRequest = new AdRequest.Builder()
// 여기서 AdRequest.Builder 클래스의 메서드를 사용하여 개별 옵션 설정을 지정할 수 있습니다.
.build();
bannerAd.loadAd(adRequest);
return bannerAd;
}
}
리소스 릴리스
Activity가 파기된 후에 콜백이 발생하면 사용된 광고 객체에 대한 destroy()
함수를 호출해 리소스를 릴리스합니다.
private fun loadBannerAd(adSize: BannerAdSize): BannerAdView {
return binding.banner.apply {
setBannerAdEventListener(object : BannerAdEventListener {
override fun onAdLoaded() {
// 활동이 훼손된 후에 이 콜백이 발생하면
// destroy를 호출하고 반환해야 하며 그렇지 않으면 메모리가 누출될 수 있습니다.
// `isDestroyed`은(는) Activity의 메서드입니다.
if (isDestroyed) {
bannerAd?.destroy()
return
}
}
...
})
...
}
}
@NonNull
private BannerAdView loadBannerAd(@NonNull final BannerAdSize adSize) {
final BannerAdView bannerAd = mBinding.banner;
bannerAd.setBannerAdEventListener(new BannerAdEventListener() {
@Override
public void onAdLoaded() {
// 활동이 훼손된 후에 이 콜백이 발생하면
// destroy를 호출하고 반환해야 하며 그렇지 않으면 메모리가 누출될 수 있습니다.
// `isDestroyed`은(는) Activity의 메서드입니다.
if (isDestroyed() && mBannerAd != null) {
mBannerAd.destroy();
}
}
...
});
...
return bannerAd;
}
적응형 스티키 배너 통합 테스트
광고 테스트를 위한 데모 광고 단위 사용
적응형 스티키 배너 통합 및 앱 자체를 테스트하기 위해 테스트 광고를 사용하는 것이 좋습니다.
모든 광고 요청에 대해 테스트 광고가 반환되도록 보장하기 위해 특별한 데모 광고 배치 ID를 생성했습니다. 광고 통합을 확인하는 데 사용하세요.
데모 adUnitId: demo-banner-yandex
.
Важно
앱을 스토어에 게시하기 전에 데모 배치 ID를 Yandex Advertising Network 인터페이스에서 획득한 실제 ID로 교체해야 합니다.
사용 가능한 데모 광고 배치 ID 목록은 테스트용 데모 광고 단위 섹션에서 찾을 수 있습니다.
광고 통합 테스트
SDK의 내장 분석기를 사용하여 적응형 스티키 배너 통합을 확인할 수 있습니다.
이 도구는 광고가 제대로 통합되었는지 확인하고 로그에 상세한 보고서를 출력합니다. 보고서를 보려면 Android 앱 디버깅을 위한 Logcat 도구에서 "YandexAds" 키워드를 검색하세요.
adb logcat -v brief '*:S YandexAds'
통합에 성공하면 다음 메시지가 표시됩니다.
adb logcat -v brief '*:S YandexAds'
mobileads$ adb logcat -v brief '*:S YandexAds'
I/YandexAds(13719): [Integration] Ad type banner was integrated successfully
배너 광고 통합에 문제가 있는 경우, 문제에 대한 상세한 보고서와 해결 방법에 대한 권장 사항을 받게 됩니다.
추가 리소스
-
GitHub 링크.