Android 네이티브 광고

1. xml 으로 네이티브 광고 레이아웃 만들기

네이티브 광고에서는 다음과 같은 view의 종류들이 포함될 수 있습니다.

  • 아이콘

  • 광고 게시자

  • 헤드라인

  • 바디

  • 미디어

  • CTA 버튼

예를 들어, 소셜 피드 형식의 네이티브 광고를 구성한다면 다음과 같은 레이아웃을 만들 수 있습니다.

  • AdropNativeAdView - parent view

    ⌞ Logo (ImageView)

    ⌞ Name (TextView)

    ⌞ Media (AdropMediaView)

    ⌞ Headline (TextView) ⌞ Body (TextView)

  • 제목, 내용, 소재 이미지는 컴포넌트를 제공하지만 자유롭게 사용하실 수 있도록 필드 데이터를 제공합니다.

<!-- activity_main.xml -->
<io.adrop.ads.nativeAd.AdropNativeAdView
    android:id="@+id/adrop_native_ad_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp">

        <!-- 프로필 아이콘 -->
        <ImageView
            android:id="@+id/ad_icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <!-- 광고주 이름(Advertiser/Profile Name) -->
        <TextView
            android:id="@+id/ad_advertiser"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            app:layout_constraintStart_toEndOf="@id/ad_icon"
            app:layout_constraintEnd_toStartOf="@id/call_to_action_view"
            app:layout_constraintTop_toTopOf="@id/ad_icon"
            android:layout_marginStart="8dp" />

        <!-- CTA 버튼 -->
        <TextView
            android:id="@+id/call_to_action_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingHorizontal="12dp"
            android:paddingVertical="8dp"
            android:textStyle="bold"
            android:textAllCaps="true"
            android:background="@drawable/cta_button_background"
            android:textColor="@android:color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="@id/ad_icon" />

        <!-- 미디어 -->
        <io.adrop.ads.nativeAd.AdropMediaView
            android:id="@+id/ad_media"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintTop_toBottomOf="@id/ad_icon"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintDimensionRatio="16:9" />

        <!-- 헤드라인 -->
        <TextView
            android:id="@+id/ad_headline"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:textSize="16sp"
            app:layout_constraintTop_toBottomOf="@id/ad_media"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginTop="8dp" />

        <!-- 본문 -->
        <TextView
            android:id="@+id/ad_body"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            app:layout_constraintTop_toBottomOf="@id/ad_headline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginTop="4dp" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</io.adrop.ads.nativeAd.AdropNativeAdView>

2. 네이티브 광고 불러오기

로컬 환경에서 배너 노출을 확인하고 싶다면, 아래의 TEST_UNIT_ID를 사용해주세요.

자세한 예시는 Github에서 확인하실 수 있습니다. 테스트 유닛 아이디는 프로덕션 배포시 반드시 실제 광고 유닛으로 교체해 주셔야 합니다.

Native

PUBLIC_TEST_UNIT_ID_NATIVE

Native Video (16:9)

PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_16_9

Native Video (9:16)

PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_9_16

Native Example 구현 예시

  • 필요한 파라미터 정의

class AdropUnitId {
    companion object {
        // 실 서비스용: 실제 발급받은 유닛 ID로 교체
        const val NATIVE_VIDEO_16_9 = "YOUR_NATIVE_UNIT_ID"
        const val NATIVE_IMAGE_360_360 = "YOUR_NATIVE_UNIT_ID"

        // 개발/테스트용 퍼블릭 유닛 (선택)
        const val PUBLIC_NATIVE_VIDEO_16_9 = "PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_16_9"
        const val PUBLIC_NATIVE_VIDEO_9_16 = "PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_9_16"
        const val PUBLIC_NATIVE_IMAGE_360_360 = "PUBLIC_TEST_UNIT_ID_NATIVE"
    }
}
  • 구현 예시

import android.os.Bundle
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import io.adrop.ads.model.AdropErrorCode
import io.adrop.ads.nativeAd.*

class MainActivity : AppCompatActivity() {

    private lateinit var nativeAd: AdropNativeAd
    private lateinit var nativeAdView: AdropNativeAdView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        nativeAdView = findViewById(R.id.adrop_native_ad_view)
        loadNativeAd()
    }

    private fun loadNativeAd() {
        // 개발 중: AdropUnitId.PUBLIC_NATIVE_VIDEO_16_9 등 사용 가능
        nativeAd = AdropNativeAd(this, AdropUnitId.NATIVE_VIDEO_16_9)

        // 기본 클릭 처리(권장): false
        nativeAd.useCustomClick = false

        nativeAd.listener = object : AdropNativeAdListener {
            override fun onAdReceived(ad: AdropNativeAd) {
                Log.d("AdropNative", "로드 성공: ${ad.unitId}, creative=${ad.creativeId}")
                populateNativeAdView(ad)
            }

            override fun onAdFailedToReceive(ad: AdropNativeAd, errorCode: AdropErrorCode) {
                Log.e("AdropNative", "로드 실패: $errorCode")
            }

            override fun onAdClick(ad: AdropNativeAd) {
                Log.d("AdropNative", "클릭")
            }

            override fun onAdImpression(ad: AdropNativeAd) {
                Log.d("AdropNative", "노출")
            }
        }

        nativeAd.load()
    }

    private fun populateNativeAdView(ad: AdropNativeAd) {
        // 전체 영역 클릭 가능 (옵션)
        nativeAdView.isEntireClick = true

        // 아이콘
        val iconView = findViewById<ImageView>(R.id.ad_icon)
        Glide.with(this).load(ad.profile.displayLogo).into(iconView)
        nativeAdView.setProfileLogoView(iconView)

        // 광고주 이름
        val advertiserView = findViewById<TextView>(R.id.ad_advertiser)
        advertiserView.text = ad.profile.displayName
        nativeAdView.setProfileNameView(advertiserView)

        // 헤드라인
        val headlineView = findViewById<TextView>(R.id.ad_headline)
        headlineView.text = ad.headline
        nativeAdView.setHeadlineView(headlineView)

        // 본문
        val bodyView = findViewById<TextView>(R.id.ad_body)
        bodyView.text = ad.body
        nativeAdView.setBodyView(bodyView)

        // 미디어
        val mediaView = findViewById<AdropMediaView>(R.id.ad_media)
        nativeAdView.setMediaView(mediaView)

        // 마지막에 필수로 등록!
        nativeAdView.setNativeAd(ad)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 메모리 누수 방지
        if (::nativeAdView.isInitialized) nativeAdView.destroy()
        if (::nativeAd.isInitialized) nativeAd.destroy()
    }
}

3. 네이티브 광고 연결 후 조회하기

AdropNativeAdView 의 예시와 이것을 populate한 AdropNativeAd 의 예시를 보여드립니다.

val adView: AdropNativeAdView = findViewById(R.id.adrop_native_ad_view)

fun populateNativeAdView(ad; AdropNativeAd) {
    val imageVIew = findViewById<ImageView>(R.id.ad_icon)
    // set ad.profile.displayLogo into imageView
    adView.setProfileLogoView(imageVIew)
    
    val nameView = findViewById<TextView>(R.id.ad_advertiser)
    nameView.text = ad.profile.displayName
    adView.setProfileNameView(nameView)
    
    val bodyView = findViewById<TextView>(R.id.ad_body)
    bodyView.text = ad.body
    adView.setBodyView(bodyView)
    
    val headlineView = findViewById<TextView>(R.id.ad_headline)
    headlineView.text = ad.headline
    adView.setHeadlineView(headlineView)
    
    adView.setMediaView(findViewById(R.id.ad_media))
    ...
    
    // AdropNativeAdView의 setNativeAd 메소드를 호출하여 AdropNativeAd를 등록합니다.
    adView.setNativeAd(ad)
    
    ...
}

4. 커스텀 필드 데이터 추가 및 자유로운 이미지 소재 사용하기

예를 들어, t1, t2, t3 라는 커스텀 필드가 추가 되었을 경우에 대해 알아보겠습니다. * 텍스트 라벨은 광고주 콘솔에 입력되는 라벨입니다.

findViewById<TextView>(R.id.t1).text = ad.extra.optString("t1")
findViewById<TextView>(R.id.t2).text = ad.extra.optString("t2")
findViewById<TextView>(R.id.t3).text = ad.extra.optString("t3")

5. 속성 설명

  • useCustomClick

    • false(기본): SDK가 클릭을 자동 처리 (권장)

    • true: 개발자가 클릭을 직접 처리

  • isEntireClick / setEntireClick(true)

    • 네이티브 광고 전체 영역을 클릭 가능하게 설정

  • AdropMediaView

    • 컴포넌트 (비디오/이미지 소재를 표시)

​적용 확인하기​

console에서 발급받은 unitId가 한 번이라도 광고요청을 할 경우 성공적으로 연결됩니다.

광고 유닛에 연결된 광고가 없다면, 네이티브가 랜더링 되지 않습니다. 따라서 네이티브가 정상적으로 랜더링 되는지 확인하고 싶으면, TEST_UNIT_ID 를 사용해 주세요.

TEST_UNIT_ID 를 사용하면 네이티브 랜더링 확인은 할 수 있지만, console과 연결되지는 않습니다. 따라서 성공적인 연결을 확인하려면 콘솔에 등록한 광고 유닛의 아이디를 적용해 주시고, 하단 이미지 처럼 콘솔을 확인해 주세요.

Last updated