facebook audience-network

2020. 12. 9. 15:52 안드로이드/개발 TIP

앱을 개발했으면 수익을 창출해 볼 시간입니다.

수익을 창출하는 방법은 여러가지가 있겠지만 가장 접근하기 쉬운것이 광고가 아닐까 합니다.

이번 시간에는 facebook의 광고플랫폼인 audience-network에 대해 포스팅하겠습니다.


https://developers.facebook.com/ 로 이동합니다.



개발자페이지에 가입을 하고 프로젝트를 만듭니다. 만드는 자세한 사항은 다큐먼트를 참조하여도 좋습니다.






프로젝트를 만든 후 프로젝트를 클릭하여 이동하면 좌측 상단에 여러가지 메뉴늘 볼 수 있습니다.

앱 이름 우측의 화살표를 클릭하면 테스트를 만들 수 있는 기능도 제공합니다.






우리가 필요한것은 audience-network 이기 때문에 audience-network 를 선택합니다.

페이스북 광고플랫폼을 붙이기 위해서는 여러가지 선행조건이 요구되는데 자세한 설명은 다큐먼트를 참조하십시오.



광고 노출 위치 만들기를 클릭하면 다음과 같은 화면을 볼 수 있습니다.

배너, 전면, 네이티브를 선택할 수 있고 활성화, 비활성화도 시킬 수 있습니다.


광고를 만든 후 코드받기를 클릭해볼까요?


ios와 android에서 어떻게 코드를 사용할 것인지 샘플을 보여주고 있습니다. 

그대로 따라만 하시면 됩니다. 

혹은 다큐먼트를 참조하세요

https://developers.facebook.com/docs/audience-network/android/native-api




그리고 정산을 받기 위해서 여러가지 정보를 입력해야하는데 

그 중 하나가 회사 정보와 납세자 정보입니다.

input창 안에서는 영문과 한글 모두 쓸 수있지만 한글로 표기하면 전송시 경고문구가 뜹니다.

그렇기에 모두 영문으로 작성해주세요.

일반 개인은 납세자 번호 유형에 납세자 번호(기타)를 선택합니다.



그리고 필수 세금 관련문서는 W-8BEN 미국 외 개인납세자 용을 다운받아 작성하시기 바랍니다.

페이스북에서는 필수항목만 기재하면 되며, 대부분 아는 선 내에서 작성하시면 됩니다.

그리고 파일을 첨부하여 업데이트를 하세요. 승인이 2일안에 난다고 하지만 전 몇시간 안에 승인되었습니다.



이제부터는 어떻게 코드를 작성하는지 알아봅시다.


다시한번 말씀드리지만 다큐먼트를 참고하시는게 더 도움이 될 수 있습니다 ㅎㅎ

https://developers.facebook.com/docs/audience-network/android/native-api



배너는 다음과 같이 AdView를 init시켜준 후 layout에 add시키면 됩니다.



AdView facebook = new AdView(adLayout.getContext(), context.getString(R.string.facebook_banner_id), AdSize.BANNER_HEIGHT_50);
adLayout.addView(facebook);
facebook.setAdListener(adListener);
facebook.loadAd();

private AdListener adListener = new AdListener() {
@Override
public void onError(Ad ad, AdError adError) {

}

@Override
public void onAdLoaded(Ad ad) {

}

@Override
public void onAdClicked(Ad ad) {

}
};



배너 실제 적용모습.



종료 다이얼로그



view = LayoutInflater.from(context).inflate(R.layout.widget_ad_native_dialog, null);

facebookLayout = (LinearLayout) view.findViewById(R.id.ad_native_facebook_layout);
admobLayout = (LinearLayout) view.findViewById(R.id.ad_native_admob_layout);

adChoice = (RelativeLayout) view.findViewById(R.id.ad_native_choice);
adIcon = (ImageView) view.findViewById(R.id.ad_native_icon);
adContext = (TextView) view.findViewById(R.id.ad_native_context);
adAction = (TextView) view.findViewById(R.id.ad_native_action);
adCover = (ImageView) view.findViewById(R.id.ad_native_cover);
adTitle = (TextView) view.findViewById(R.id.ad_native_title);
adBody = (TextView) view.findViewById(R.id.ad_native_body);

nativeAd = new NativeAd(context, context.getString(R.string.facebook_native_id));
nativeAd.setAdListener(adListener);

builder = new MaterialDialog.Builder(context);
builder.title(R.string.dialog_app_finish
);
builder.customView(view, false);
builder.negativeText(android.R.string.no);
builder.positiveText(android.R.string.yes);
builder.cancelListener(cancleListener);
builder.onPositive(callback);
builder.show();

nativeAd.loadAd();

/**
* facebook ad listener
*/
private AdListener adListener = new AdListener() {

/**
* if get error facebook ad, get admob ad
* @param ad
* @param adError
*/
@Override
public void onError(Ad ad, AdError adError) {

}


/**
* set data when loaded facebook ad
* @param ad
*/
@Override
public void onAdLoaded(Ad ad) {
if (ad != nativeAd) {
return;
}

// Add adChoices icon
adChoicesView = new AdChoicesView(context, nativeAd, true);
adChoice.addView(adChoicesView, 0);

// Setting
NativeAd.downloadAndDisplayImage(nativeAd.getAdIcon(), adIcon);
adContext.setText(nativeAd.getAdSocialContext());
adAction.setText(nativeAd.getAdCallToAction());
adTitle.setText(nativeAd.getAdTitle());
adBody.setText(nativeAd.getAdBody());

nativeAd.registerViewForInteraction(facebookLayout);
facebookLayout.setVisibility(View.VISIBLE);

// image
NativeAd.downloadAndDisplayImage(nativeAd.getAdCoverImage(), adCover);
}

@Override
public void onAdClicked(Ad ad) {
}
};


종료 다이얼로그 실제 적용모습




RecyclerView 혹은 ListView에서의 적용은 상당히 까다롭습니다.

하나의 NativeAd당 loadAd를 한번씩 밖에 할 수 없기 때문에 중복이 나면 바로 exception에러가 납니다.

또한 Viewholder패턴을 쓰면 하나의 광고만 동일하게 반복됩니다.


이를 해결하기 ViewHolder패턴과 Vo를 적극 이용하였습니다.



우선 Vo내부 일부분입니다.

현재 데이터 타입이 광고인지 판단하는 bool형 변수와 NativeAd를 선언하였습니다.

여기서 Gson을 이용하신다면 Gson내부의 처리 로직에서 파싱시 error가 나기 때문에 Gson에서 파싱을 제외하는 transient 구문을 꼭 넣어주세요.

@SerializedName("eventstartdate")
private String eventstartdate;

private boolean isAdvertise;
private transient NativeAd nativeAd;


그리고 페이징처리를 통해 가져온 list의 마지막에 vo를 하나더 추가하시면 됩니다. 마지막은 광고를 위한 것이겠죠 ㅎ

TourData tourData = new TourData();
tourData.setAdvertise(true);
list.getItem().add(tourData);
adapter.setData(list.getItem());


그리고 adpater 내부에도 작업이 필요로 하는데요

광고item과 광고가 아닌 item으로 나누어주세요.

@Override
public int getItemViewType(int position) {
int viewType = getItem(position).isAdvertise() ? 2 : 1; // 1: data / 2: ad
return viewType;
}



Viweholder패턴을 itemViewType에 맞게 설정합니다.

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
RecyclerView.ViewHolder viewHolder;
if(viewType == 1){
view = inflater.inflate(R.layout.fragment_tour_row, parent, false);
viewHolder = new ViewHolder(view);
}else{
view = inflater.inflate(R.layout.widget_ad_native_list, parent, false);
viewHolder = new AdListViewHolder(view);
}

return viewHolder;
}


이것이 핵심입니다.
onBindViewHolder에서 리스트가 돌면서 광고item을 발견했다면 item내부의 NativeAd가 null인지 체크를 합니다.
당연히 boolean 변수에만 값을 적용했으니 null입니다.
null이면 새로운 NativeAd를 init시켜주고 광고를 load시킵니다.
그리고 Vo에 NativeAd를 set해주세요. 

스크롤하다 다시 제자리도 돌아올 때 vo의 NativeAd를 체크하여 있는 것들은 광고를 새로 init하지 않고 안에 있는 NativeAd를 가져와
재사용해주기만 하면 됩니다.

TourData data = tourDatas.get(position);
if(data.isAdvertise()){
final AdListViewHolder dataHolder = (AdListViewHolder) holder;
if(null == data.getNativeAd()){
final NativeAd nativeAd = NativeAdManager.getInstance().initNativeAd(context);
data.setNativeAd(nativeAd);
nativeAd.loadAd();

nativeAd.setAdListener(new AdListener() {
@Override
public void onError(Ad ad, AdError adError) {
Log.e("test", adError.getErrorMessage());
}

@Override
public void onAdLoaded(Ad ad) {
if (null == nativeAd) {
return;
}

// Add adChoices icon
dataHolder.adChoicesView = new AdChoicesView(context, nativeAd, true);
dataHolder.choicesView.addView(dataHolder.adChoicesView, 0);

// Setting
NativeAd.downloadAndDisplayImage(nativeAd.getAdIcon(), dataHolder.icon);
dataHolder.content.setText(nativeAd.getAdSocialContext());
dataHolder.action.setText(nativeAd.getAdCallToAction());
dataHolder.title.setText(nativeAd.getAdTitle());
dataHolder.body.setText(nativeAd.getAdBody());

nativeAd.registerViewForInteraction(dataHolder.layout);
dataHolder.layout.setVisibility(View.VISIBLE);

// image
NativeAd.downloadAndDisplayImage(nativeAd.getAdCoverImage(), dataHolder.cover);
}

@Override
public void onAdClicked(Ad ad) {

}
});
}else{
NativeAd nativeAd = data.getNativeAd();
// Add adChoices icon
dataHolder.adChoicesView = new AdChoicesView(context, nativeAd, true);
dataHolder.choicesView.addView(dataHolder.adChoicesView, 0);

// Setting
NativeAd.downloadAndDisplayImage(nativeAd.getAdIcon(), dataHolder.icon);
dataHolder.content.setText(nativeAd.getAdSocialContext());
dataHolder.action.setText(nativeAd.getAdCallToAction());
dataHolder.title.setText(nativeAd.getAdTitle());
dataHolder.body.setText(nativeAd.getAdBody());

nativeAd.registerViewForInteraction(dataHolder.layout);
dataHolder.layout.setVisibility(View.VISIBLE);

// image
NativeAd.downloadAndDisplayImage(nativeAd.getAdCoverImage(), dataHolder.cover);
}
}



RecyclerView에 실제 적용한 모습.



전면광고는 여러분의 몫으로 남겨놓겠습니다..





모두 해피한 개발하세요~


도움이 되셨다면 좋아요 꾹~

출처만 남겨놓는다면 마음껏 퍼가셔도 좋습니다~ 






* 페이스북 광고 플랫폼의 절차적인 내용은 박상권님의 설명을 듣고 참고하였습니다.

감사드립니다.



박상권님의 블로그

http://gun0912.tistory.com/



출처: https://akaisun.tistory.com/27?category=622886 [아카이의 개발창고]