티스토리 뷰

안드로이드

facebook audience-network

아카이sun 2016.06.18 20:29

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

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

이번 시간에는 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/
















댓글
  • 프로필사진 박상권 좋은정보 감사합니다. 2016.07.01 09:02 신고
  • 프로필사진 아카이sun 감사합니다. Ted Permission잘쓰고 있습니다 ㅎㅎ 2016.07.01 09:06 신고
  • 프로필사진 스티브 좋은 정보 진심으로 감사합니다. 광고 관련 업데이트 소식 받아볼 수 있을까요? 2016.07.13 10:49 신고
  • 프로필사진 아카이sun 본 블로그는 개발관련 블로그이기에 따로 광고관련해서 포스팅을 하지 않고 있습니다. 다만 좋은 정보가 있다면 공유 차원에서 포스팅을 하고 있습니다. 2016.07.13 10:56 신고
  • 프로필사진 이태수 개인개발자입니다. 납세자번호는 뭘 입력해야되는건가요? 주민등록번호인가요?ㅠ
    사업자등록이 필요한건가요?
    2016.08.11 14:56 신고
  • 프로필사진 아카이sun 개인개발자는 개인정보가 식별가능한 정보를 입력하면 될 듯 합니다. 2016.08.11 15:00 신고
  • 프로필사진 이태수 "개인정보가 식별가능한 정보"라 함은 무엇을 의미하는건가요?
    ITIN을 신청해야되는건가요?
    실제 지급까지 받아보셨나요?
    괜히 주민등록번호 입력했다가 나중에 더 골치 아파질까 걱정이라서요..
    2016.08.11 15:16 신고
  • 프로필사진 k샘 아까 단톡방에 올려주신거 보고 있는데요 adLayout.addView(facebook);에서
    adLayout은 어디서 나오는건가요? 페북 튜터리얼에도 없던데... 죄송해요 초보라서요
    2016.12.13 14:19 신고
  • 프로필사진 아카이sun 네이티브가 표시될 레이아웃입니다. xml로 미리 잡아둔 곳에 add하시면되요 2016.12.13 14:25 신고
  • 프로필사진 k샘 샘플통합코드로 해서 보았지만 잘모르겠느데 제가 초보인지라 ..
    혹시 예제소스 있으신지요...
    죄송합니다.
    2016.12.13 14:44 신고
  • 프로필사진 아카이sun 제가 작성한 예제는 없고 여기 참조해보세요

    https://github.com/fbsamples/audience-network-support/blob/master/samples/android/NativeAd/app/src/main/java/com/sample/nativead/NativeAdActivity.java
    2016.12.13 14:54 신고
  • 프로필사진 SSHOW 적용중인데 2주넘게 제자리상태입니다. "Audience-Network 빠른시작" 단계화면에서는 2단계인 '광고요청 보내기'에서 멈춰있고, 제품 > Audience Network>앱 탭에서는 ... "검수중"으로 표시되고 있습니다. (실제 저의 폰에서는 광고가 노출되고 있습니다.) 안드로이드용 코드를 적용하여 구글 PlayStore에도 업데이트 되어 있는 상태입니다. 페이스북 고객센터에 문의메일을 보내도 답변도 없어 답답하네요..!!! 제품 > Audience Network 에서 앱추가,노출위치,정산정보 입력외에 상위 카테고리인 앱(제품?)단계에서도 별도의 설정이 필요한것이 있는지 혹시 아시는분? 2017.02.28 20:32 신고
  • 프로필사진 namoo 저와 같은 현상이네요.. 지금은 해결하셨나요? 2017.05.03 19:54 신고
  • 프로필사진 문의합닏 이렇게 하면 FaceBook AD가 load fail 일 때 광고영역이 비어진 상태로 보여지지 않나요? 2017.08.03 01:18 신고
  • 프로필사진 아카이sun load fail일때는 당연히 광고가 나오지 않습니다. 따라서 미디에이션 또는 visiblity를 적정히 써주셔야합니다 2018.01.23 11:21 신고
  • 프로필사진 이동훈 안녕하세요. 글 잘 보았습니다.
    글보고 문의가 있어서 댓글 남겨봅니다.
    viewholder 패턴과 vo를 활용했다고 본문에 적혀 있는데요, vo 라는 것은 어떤 것을 말씀하시는 건지요?
    2018.01.23 11:17 신고
  • 프로필사진 아카이sun 계층간 데이터 교환을 위한 자바빈즈라고 어디에서 설명하더군요.

    vo는 value object의 축약단어입니다.
    2018.01.23 11:20 신고
댓글쓰기 폼