Android 앱에 네이티브 광고 추가

네이티브 광고 API를 사용하면 앱에 표시되는 광고를 위한 맞춤 경험을 빌드할 수 있습니다. 게시할 준비가 된 광고를 수신하는 대신 네이티브 광고 API를 사용하는 경우 제목, 이미지, 행동 유도와 같은 광고 속성 그룹이 제공되므로 이러한 광고 속성을 사용하여 광고가 표시될 맞춤 설정 보기를 구성해야 합니다.

계속하기 전에 Audience Network 시작하기Android 시작하기 가이드를 완료했는지 확인하세요.

이 가이드에서는 다음과 같은 네이티브 광고 노출 위치를 구현합니다. 다음의 구성 요소를 사용하여 네이티브 광고를 만들어보겠습니다.

보기 #1: 광고 아이콘

보기 #2: 광고 제목

보기 #3: 광고 레이블

보기 #4: AdOptionsView

보기 #5: MediaView

보기 #6: 소셜 컨텍스트

보기 #7: 광고 본문

보기 #8: 행동 유도 버튼




네이티브 광고 단계

1단계: 네이티브 광고 요청

2단계: 네이티브 광고 레이아웃 만들기

3단계: 광고 메타데이터를 사용하여 레이아웃 채우기

4단계: MediaView 사용하기

5단계: 자동 캐시 없이 광고 읽어들이기

Audience Network SDK 초기화

이 메서드는 Android Audience Network SDK 버전 5.1에 추가되었습니다.

5.3.0 버전 이상에서는 Audience Network Android SDK의 명시적 초기화가 필수입니다. Audience Network Android SDK를 초기화하는 방법은 이 문서를 참조하세요.

개체를 만들고 광고를 읽어들이기 전에 먼저 Audience Network SDK를 초기화해야 합니다. 이 작업은 앱 실행 시에 하는 것이 좋습니다.

public class YourApplication extends Application {
    ...
    @Override
    public void onCreate() {
        super.onCreate();
        // Initialize the Audience Network SDK
        AudienceNetworkAds.initialize(this);       
    }
    ...
}

1단계: 네이티브 광고 요청

활동의 맨 위에 다음 코드를 추가하여 Facebook 광고 SDK를 가져옵니다.

import com.facebook.ads.*;

그런 다음, NativeAd 개체를 인스턴스화하고 NativeAdListener를 만들어 광고 리스너로 loadAd()를 호출합니다.

private final String TAG = "NativeAdActivity".getClass().getSimpleName();
private NativeAd nativeAd;

private void loadNativeAd() {
    // Instantiate a NativeAd object.
    // NOTE: the placement ID will eventually identify this as your App, you can ignore it for
    // now, while you are testing and replace it later when you have signed up.
    // While you are using this temporary code you will only get test ads and if you release
    // your code like this to the Google Play your users will not receive ads (you will get a no fill error).
    nativeAd = new NativeAd(this, "YOUR_PLACEMENT_ID");

    NativeAdListener nativeAdListener = new NativeAdListener() {
        @Override
        public void onMediaDownloaded(Ad ad) {
            // Native ad finished downloading all assets
            Log.e(TAG, "Native ad finished downloading all assets.");
        }

        @Override
        public void onError(Ad ad, AdError adError) {
        // Native ad failed to load
            Log.e(TAG, "Native ad failed to load: " + adError.getErrorMessage());
        }

        @Override
        public void onAdLoaded(Ad ad) {
            // Native ad is loaded and ready to be displayed
            Log.d(TAG, "Native ad is loaded and ready to be displayed!");
        }

        @Override
        public void onAdClicked(Ad ad) {
            // Native ad clicked
            Log.d(TAG, "Native ad clicked!");
        }

        @Override
        public void onLoggingImpression(Ad ad) {
            // Native ad impression
            Log.d(TAG, "Native ad impression logged!");
        }
    };

    // Request an ad
    nativeAd.loadAd(
            nativeAd.buildLoadAdConfig()
                    .withAdListener(nativeAdListener)
                    .build());
}

나중에 다시 돌아와 onAdLoaded() 메서드에 코드를 추가할 것입니다.

2단계: 네이티브 광고 레이아웃 만들기

다음 단계에서는 광고 메타데이터를 추출하고 해당 속성을 사용하여 맞춤 설정 네이티브 UI를 빌드합니다. 레이아웃 .xml에서 맞춤 설정 보기를 만들거나 코드에 요소를 추가할 수 있습니다.

앱에서 네이티브 광고를 디자인할 때 네이티브 광고 가이드라인을 참조하세요.

활동의 레이아웃 activity_main.xml에서 Native Ad의 컨테이너를 추가합니다. 컨테이너는 com.facebook.ads.NativeAdLayout이어야 합니다. 이는 FrameLayout을 기반으로 하고 광고 위에서 네이티브 광고 보고 플로를 렌더링할 수 있는 몇 가지 추가 기능이 포함된 래퍼입니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:paddingTop="50dp">
    ...
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="50dp">

        <com.facebook.ads.NativeAdLayout
             android:id="@+id/native_ad_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical" />
     </ScrollView>
    ...
</RelativeLayout>

네이티브 광고를 위한 맞춤 설정 레이아웃 native_ad_layout.xml을 만듭니다.



네이티브 광고의 맞춤 설정 레이아웃의 예는 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ad_unit"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:orientation="vertical"
    android:paddingLeft="10dp"
    android:paddingRight="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingBottom="10dp"
        android:paddingTop="10dp">

        <com.facebook.ads.MediaView
            android:id="@+id/native_ad_icon"
            android:layout_width="35dp"
            android:layout_height="35dp" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="5dp"
            android:paddingRight="5dp">

        <TextView
            android:id="@+id/native_ad_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:lines="1"
            android:textColor="@android:color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/native_ad_sponsored_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:lines="1"
            android:textColor="@android:color/darker_gray"
            android:textSize="12sp" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/ad_choices_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="end"
        android:orientation="horizontal" />

    </LinearLayout>

    <com.facebook.ads.MediaView
        android:id="@+id/native_ad_media"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="5dp">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:orientation="vertical">

            <TextView
                android:id="@+id/native_ad_social_context"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:textColor="@android:color/darker_gray"
                android:textSize="12sp" />

            <TextView
                android:id="@+id/native_ad_body"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:gravity="center_vertical"
                android:lines="2"
                android:textColor="@android:color/black"
                android:textSize="12sp" />

        </LinearLayout>

        <Button
            android:id="@+id/native_ad_call_to_action"
            android:layout_width="100dp"
            android:layout_height="30dp"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:background="#4286F4"
            android:paddingLeft="3dp"
            android:paddingRight="3dp"
            android:textColor="@android:color/white"
            android:textSize="12sp"
            android:visibility="gone" />

    </LinearLayout>

</LinearLayout>

3단계: 광고 메타데이터를 사용하여 레이아웃 채우기

시나리오 1: 광고가 성공적으로 읽어들여지면 즉시 표시합니다. 위의 onAdLoaded() 메서드를 수정하여 Native Ad's 속성을 가져오고 아래와 같이 표시합니다.

private NativeAdLayout nativeAdLayout;
private LinearLayout adView;
private NativeAd nativeAd;

private void loadNativeAd() {
    // Instantiate a NativeAd object. 
    // NOTE: the placement ID will eventually identify this as your App, you can ignore it for
    // now, while you are testing and replace it later when you have signed up.
    // While you are using this temporary code you will only get test ads and if you release
    // your code like this to the Google Play your users will not receive ads (you will get a no fill error).
    nativeAd = new NativeAd(this, "YOUR_PLACEMENT_ID");

    NativeAdListener nativeAdListener = new NativeAdListener() {
        ...
        @Override
        public void onAdLoaded(Ad ad) {
            // Race condition, load() called again before last ad was displayed
            if (nativeAd == null || nativeAd != ad) {
                return;
            }
            // Inflate Native Ad into Container
            inflateAd(nativeAd);
        }
        ...
    };

    // Request an ad
    nativeAd.loadAd(
            nativeAd.buildLoadAdConfig()
                    .withAdListener(nativeAdListener)
                    .build());
}

private void inflateAd(NativeAd nativeAd) {

    nativeAd.unregisterView();

    // Add the Ad view into the ad container.
    nativeAdLayout = findViewById(R.id.native_ad_container);
    LayoutInflater inflater = LayoutInflater.from(NativeAdActivity.this);
    // Inflate the Ad view.  The layout referenced should be the one you created in the last step.
    adView = (LinearLayout) inflater.inflate(R.layout.native_ad_layout_1, nativeAdLayout, false);
    nativeAdLayout.addView(adView);

    // Add the AdOptionsView
    LinearLayout adChoicesContainer = findViewById(R.id.ad_choices_container);
    AdOptionsView adOptionsView = new AdOptionsView(NativeAdActivity.this, nativeAd, nativeAdLayout);
    adChoicesContainer.removeAllViews();
    adChoicesContainer.addView(adOptionsView, 0);

    // Create native UI using the ad metadata.
    MediaView nativeAdIcon = adView.findViewById(R.id.native_ad_icon);
    TextView nativeAdTitle = adView.findViewById(R.id.native_ad_title);
    MediaView nativeAdMedia = adView.findViewById(R.id.native_ad_media);
    TextView nativeAdSocialContext = adView.findViewById(R.id.native_ad_social_context);
    TextView nativeAdBody = adView.findViewById(R.id.native_ad_body);
    TextView sponsoredLabel = adView.findViewById(R.id.native_ad_sponsored_label);
    Button nativeAdCallToAction = adView.findViewById(R.id.native_ad_call_to_action);

    // Set the Text.
    nativeAdTitle.setText(nativeAd.getAdvertiserName());
    nativeAdBody.setText(nativeAd.getAdBodyText());
    nativeAdSocialContext.setText(nativeAd.getAdSocialContext());
    nativeAdCallToAction.setVisibility(nativeAd.hasCallToAction() ? View.VISIBLE : View.INVISIBLE);
    nativeAdCallToAction.setText(nativeAd.getAdCallToAction());
    sponsoredLabel.setText(nativeAd.getSponsoredTranslation());

    // Create a list of clickable views
    List<View> clickableViews = new ArrayList<>();
    clickableViews.add(nativeAdTitle);
    clickableViews.add(nativeAdCallToAction);

    // Register the Title and CTA button to listen for clicks.
    nativeAd.registerViewForInteraction(
            adView, nativeAdMedia, nativeAdIcon, clickableViews);
}

SDK에서 노출을 로깅하고 클릭을 자동으로 처리합니다. 이를 사용하려면 NativeAd 인스턴스로 광고 보기를 등록해야 합니다. 보기의 모든 광고 요소를 클릭할 수 있도록 하려면 다음을 통해 등록합니다.

registerViewForInteraction(View view, MediaView adMediaView, MediaView adIconView)

NativeAds와 registerViewForInteraction을 사용하면 SDK는 경쟁을 피하기 위해 호출이 메인 스레드에서 실행되는지 검사합니다. Facebook에서는 Preconditions.checkIsOnMainThread()를 사용하여 검사를 수행합니다. 백그라운드 스레드에서 registerViewForInteraction을 호출하려고 시도하면 앱이 중단되므로 구현 작업이 해당 표준을 준수하는지 확인하세요.

시나리오 2: 광고가 성공적으로 읽어들여지면 몇 초 또는 몇 분 이내에 광고가 표시됩니다. 광고가 표시되기 전에 무효화되지 않았는지 확인해야 합니다.

광고가 로드된 후 즉시 표시되지 않는 경우 개발자는 광고의 무효화 여부를 확인해야 합니다. 광고가 성공적으로 로드되면 60분간 유효합니다. 무효화된 광고를 표시하면 후원을 받지 합니다. 광고를 검증하려면 isAdInvalidated()를 호출해야 합니다.

아래의 아이디어를 따르되 코드는 예시일 뿐이므로 코드를 프로젝트에 복사하지 마세요.

private NativeAd nativeAd;

private void loadNativeAd() {
    // Instantiate a NativeAd object. 
    // NOTE: the placement ID will eventually identify this as your App, you can ignore it for
    // now, while you are testing and replace it later when you have signed up.
    // While you are using this temporary code you will only get test ads and if you release
    // your code like this to the Google Play your users will not receive ads (you will get a no fill error).
    nativeAd = new NativeAd(this, "YOUR_PLACEMENT_ID");

    NativeAdListener nativeAdListener = new NativeAdListener() {
        ...
    };

    // Request an ad
    nativeAd.loadAd(
            nativeAd.buildLoadAdConfig()
                    .withAdListener(nativeAdListener)
                    .build());

    // Here is just an example for displaying the ad with delay
    // Please call this method at appropriate timing in your project
    showNativeAdWithDelay();
}

private void showNativeAdWithDelay() {
    /**
     * Here is an example for displaying the ad with delay;
     * Please do not copy the Handler into your project
     */
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        public void run() {
            // Check if nativeAd has been loaded successfully
            if(nativeAd == null || !nativeAd.isAdLoaded()) {
                return;
            }
            // Check if ad is already expired or invalidated, and do not show ad if that is the case. You will not get paid to show an invalidated ad.
            if(nativeAd.isAdInvalidated()) {
                return;
            }
            inflateAd(nativeAd); // Inflate NativeAd into a container, same as in previous code examples
        }
    }, 1000 * 60 * 15); // Show the ad after 15 minutes
}

클릭 가능한 영역 제어

사용자 환경을 개선하고 더 나은 결과를 얻으려면 항상 광고의 클릭 가능한 영역을 제어하여 의도치 않은 클릭을 피해야 합니다. 클릭할 수 없는 여백 정책에 대한 자세한 내용은 Audience Network SDK 정책을 참조하세요.

클릭 가능한 영역을 더욱 세밀하게 제어하려면 registerViewForInteraction(View view, MediaView adMediaView, MediaView adIconView, List<View> clickableViews)를 사용하여 클릭 가능한 보기 리스트를 등록합니다. 예를 들어 위의 예시에서 광고 제목과 행동 유도 버튼만 클릭할 수 있도록 하려면 다음과 같이 코드를 작성합니다.

@Override
public void onAdLoaded(Ad ad) {
    ...
    // Create a list of clickable views
    List<View> clickableViews = new ArrayList<>();
    clickableViews.add(nativeAdTitle);
    clickableViews.add(nativeAdCallToAction);

    // Register the Title and CTA button to listen for clicks.
    nativeAd.registerViewForInteraction(
            adView, nativeAdMedia, nativeAdIcon, clickableViews);
    ...
}

시간이 지난 후 이 보기를 다시 사용하여 다른 광고를 표시할 경우 unregisterView()를 호출한 후 NativeAd의 다른 인스턴스로 동일한 보기를 등록해야 합니다.

코드를 실행하면 네이티브 광고가 보일 것입니다.

4단계: MediaView 사용하기

네이티브 광고 커버 이미지를 표시할 경우 이미지와 동영상 자산을 모두 표시할 수 있는 Meta Audience Network MediaView를 필수적으로 사용해야 합니다. 네이티브 동영상 광고 유닛의 디자인 가이드라인은 여기를 참조하세요.

기본적으로 이미지와 동영상 자산은 네이티브 광고를 읽어들일 때 모두 사전 캐시됩니다. 그러면 nativeAd가 읽어들이는 것을 완료하는 즉시 MediaView에서 동영상이 재생됩니다.

private void loadNativeAd() {
    ...
    nativeAd.loadAd();
}

또한 네이티브 광고를 읽어들일 때 명시적으로 NativeAd.MediaCacheFlag.ALL을 지정할 수도 있습니다.

private void loadNativeAd() {
    ...
    nativeAd.loadAd(
            nativeAd.buildLoadAdConfig()
                    .withMediaCacheFlag(NativeAdBase.MediaCacheFlag.ALL)
                    .build());
}

Audience Network는 NativeAd.MediaCacheFlag enum에서 정의된 대로 네이티브 광고에서 두 개의 캐시 옵션을 지원합니다.

캐시 상수 설명

ALL

모두 사전 캐시(아이콘, 이미지 및 동영상), 기본값

NONE

사전 캐시하지 않음

광고를 읽어들이면 다음 속성에 title, icon, coverImage, callToAction 등의 값이 포함됩니다. 다른 속성은 null이거나 비어 있을 수 있습니다. 이러한 사례를 처리할 수 있도록 코드를 안정화하세요.

표시할 광고가 없을 경우 error.code와 함께 onError가 호출됩니다. 자체 맞춤 설정 보고 또는 미디에이션 레이어를 사용할 경우, 코드 값을 검사하고 이 사례를 탐지하는 것이 좋습니다. 이 경우에는 다른 광고 네트워크로 폴백해도 되지만 그 직후에 광고를 다시 전송하지 마세요.

수신하는 광고 메타데이터는 캐시하여 최대 1시간 동안 다시 사용할 수 있습니다. 이 시간이 지난 후 메타데이터를 사용하려면 새 광고를 읽어들이기 위한 호출을 보내야 합니다.

5단계: 자동 캐시 없이 광고 읽어들이기

  • 기본적으로 항상 미디어 캐싱을 활성화시키는 것이 좋습니다. 그러나 loadAd 메서드에서 MediaCacheFlag.NONE을 사용하여 기본값을 다시 정의할 수 있습니다. 기본 미디어 캐싱을 다시 정의하기로 결정할 때는 매우 신중하셔야 합니다.
private final String TAG = NativeAdActivity.class.getSimpleName();
private NativeAd nativeAd;

private void loadNativeAd() {
    // Instantiate a NativeAd object. 
    // NOTE: the placement ID will eventually identify this as your App, you can ignore it for
    // now, while you are testing and replace it later when you have signed up.
    // While you are using this temporary code you will only get test ads and if you release
    // your code like this to the Google Play your users will not receive ads (you will get a no fill error).
    nativeAd = new NativeAd(this, "YOUR_PLACEMENT_ID");
    NativeAdListener nativeAdListener = new NativeAdListener() {
        ...
    };

    // Request an ad without auto cache
    nativeAd.loadAd(
            nativeAd.buildLoadAdConfig()
                    .withAdListener(nativeAdListener)
                    .withMediaCacheFlag(NativeAdBase.MediaCacheFlag.NONE)
                    .build());
}
  • 광고에서 onAdLoaded를 성공적으로 호출하고 나면 downloadMedia 메서드를 수동으로 호출하여 네이티브 광고의 모든 미디어를 다운로드할 수 있습니다(해당하는 경우).
@Override
public void onAdLoaded(Ad ad) {
    if (nativeAd == null || nativeAd != ad) {
        return;
    }

    nativeAd.downloadMedia();
}
  • 마지막으로 onMediaDownloaded 콜백에서 미디어 읽어들이기가 완료되면 registerViewForInteraction 메서드를 호출하고 광고를 표시할 수 있습니다.
@Override
public void onMediaDownloaded(Ad ad) {
    if (nativeAd == null || nativeAd != ad) {
        return;
    }

    inflateAd(nativeAd); // Inflate NativeAd into a container, same as in previous code examples
}

자동 캐시 없이 광고를 읽어들였고 downloadMedia를 수동으로 호출하여 다운로드를 시작하지 않았을 경우 미디어는 registerViewForInteraction이 호출되었을 때만 다운로드를 시작합니다. 해당 노출에 대해 모든 미디어를 읽어들이고 표시해야 합니다.

동영상 광고를 위한 하드웨어 가속화

Audience Network의 동영상 광고에는 하드웨어 가속화된 렌더링을 활성화해야 하며, 그렇지 않을 경우 동영상 조회 시 검은 화면이 나타날 수 있습니다. 이 제한 사항은 다음 항목에 적용됩니다.

  • 네이티브 광고의 동영상 크리에이티브
  • 삽입 광고의 동영상 크리에이티브
  • 인스트림 동영상 광고
  • 보상형 동영상

타겟 API 수준이 14(Ice Cream Sandwich, Android 4.0.1) 이상이면 하드웨어 가속화가 기본적으로 활성화되지만 앱 수준이나 활동 수준에서 명시적으로 이 기능을 활성화할 수도 있습니다.

앱 수준

앱 전체에 대하여 하드웨어 가속화를 활성화하려면 Android 매니페스트 파일의 <application> 태그에 다음과 같은 속성을 추가하세요.

<application android:hardwareAccelerated="true" ...>

활동 수준

앱에서 특정 활동에 대해서만 기능을 활성화하려면 Android 매니페스트 파일에서 <activity> 태그에 다음 속성을 추가하세요. 다음 예에서는 삽입 광고 및 보상형 동영상 렌더링에 사용되는 AudienceNetworkActivity에 대한 하드웨어 가속화를 활성화합니다.

<activity android:name="com.facebook.ads.AudienceNetworkActivity" android:hardwareAccelerated="true" .../>

다음 단계

  • 앱에 네이티브 광고를 추가하려면 네이티브 광고 템플릿 가이드를 참조하세요.

  • 네이티브 광고 사용법을 보여주는 코드 샘플을 참조하세요. NativeAdSample은 SDK의 일부로 제공되며 AudienceNetwork/samples 폴더에서 확인할 수 있습니다. IDE로 프로젝트를 가져와서 기기나 에뮬레이터에서 실행하세요.

기타 참고 자료

시작하기 가이드

Audience Network를 시작하기 위한 기술 가이드

코드 샘플

Audience Network 광고 통합 샘플

FAQ

Audience Network FAQ

네이티브 광고 템플릿

네이티브 광고를 통합하는 더욱 간편한 방법