Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Class

API

설명

BuzzAdBenefit

getPrivacyPolicyManager();

PrivacyPolicyManager 인스턴스를 반환합니다.

PrivacyPolicyManager

showConsentUI(context, new PrivacyPolicyEventListener());

개인 정보 수집 동의 UI를 표시합니다.

grantConsent();

개인 정보 수집 동의합니다.
사용자가 처음 Feed 지면에 진입하기 전에 호출하면 해당 사용자에게 개인 정보 수집 동의 UI가 보이지 않습니다.

revokeConsent();

개인 정보 수집 동의를 철회합니다.
만일 철회하게 되면 사용자가 Feed 지면에 진입하면 개인 정보 수집 동의 UI가 표시됩니다.

isConsentGranted();

개인 정보 수집 동의 여부를 확인합니다.

PrivacyPolicyEventListener

onUpdated(accepted: Boolean)

showConsentUI 에서 보여지는 UI에서 유저가 동의하면 accepted = True 로 호출됩니다. 반면 미동의시 accepted = False로 호출됩니다.

...

Feed 무한 스크롤 기능이 활성화되어 있으면 사용자에게 마지막 광고가 보였을 때 광고를 추가로 할당받습니다. 추가 요청에서 광고가 할당되지 않으면 더 이상 요청하지 않습니다. FeedConfig를 FeedConfig설정하여 무한 스크롤 기능을 비활성화할 사용하지 않을 수 있습니다. 기본적으로 Feed 무한 스크롤 기능은 활성화됩니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
    .autoLoadingEnabled(false) // Feed 무한 스크롤 기능 비활성화
    .build();

툴바 영역 자체 구현

Feed 툴바 영역의 디자인을 변경할 수 있습니다. 툴바 영역을 UI를 변경하는 방법은 2가지입니다. 아래 2가지 방법 중 하나를 선택하여 연동합니다.

...

BuzzAd Android SDK에서 제공하는 기본 UI를 수정하여 타이틀 혹은 배경색을 변경할 수 있습니다. 다음은 BuzzAd Android SDK의 기본 UI를 수정하여 툴바를 변경하는 예시입니다.

DefaultFeedToolbarHolder의 상 클래스를 구현하고, 기본으로 제공되는 기본 UI(FeedToolbar)를 사용하여 타이틀 혹은 배경색을 변경합니다. 그리고 FeedConfig에 구현한 클래스를 추가합니다.

Code Block
languagejava
public class YourFeedToolbarHolder extends DefaultFeedToolbarHolder {

    @Override
    public View getView(Activity activity, @NonNull final String unitId) {
        toolbar = new FeedToolbar(activity); // PopToolbar 에서 제공하는 기본 Template 사용
        toolbar.setTitle("YourFeedToolbarHolder");
        toolbar.setIconResource(R.drawable.your_icon);
        toolbar.setBackgroundColor(YourColor(Color.parseColor("#123456"));

        addInquiryMenuItemView(activity); // 문의하기 버튼은 이 함수를 통해 간단하게 추가 가능합니다.
        addSettingsMenuItemView(activity); // 세팅 버튼은 이 함수를 통해 간단하게 추가 가능합니다.
        addRightMenuItemView1(activity); // custom 버튼 추가
        return toolbar;
    }

    // custom 버튼 추가는 DefaultMenuLayout 를 사용하여 View 를 생성하고
    // toolbar.addRightMenuButton 를 사용하여 toolbar 에 추가합니다.
    private void addRightMenuItemView1(@NonNull final Activity activity) {
        MenuLayout menuLayout = new DefaultMenuLayout(activity, R.mipmap.ic_launcher);
        menuLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showInquiry(); // showInquiry 를 호출하여 문의하기 페이지로 연결합니다.
            }
        });
        toolbar.addRightMenuButton(menuLayout);
    }
}
Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
      .feedToolbarHolderClass(YourFeedToolbarHolder.class)
      .build();

...

Code Block
languagexml
// AndroidManifest.xml

...

<activity
    android:name="com.buzzvil.buzzad.benefit.presentation.feed.FeedBottomSheetActivity"
    android:theme="@style/YourActivityThemeCustomActivityTheme"
    tools:replace="android:theme"/>
    
...

...

헤더 영역에 BuzzAd Android SDK 에서 기본으로 제공하는 UI를 사용해 “총 적립 가능 금액“을 사용자에게 보여줍니다. UI를 변경하기 위해서는 헤더 영역을 자체 구현해야 합니다. 헤더 영역을 자체 구현하는 방법은 아래 헤더 영역 자체 구현을 참고하시기 바랍니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
      .feedHeaderViewAdapterClass(DefaultFeedHeaderViewAdapter.class)
      .build();

...

Code Block
languagejava
public class CustomFeedHeaderViewAdapter implements FeedHeaderViewAdapter {
    @Override
    public View onCreateView(final Context context, final ViewGroup parent) {
        final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        return inflater.inflate(R.layout.your_feed_header_layout, parent, false);
    }

    @Override
    public void onBindView(final View view, final int reward) {
        // Display total reward on the header if needed.
        finalval ViewtextView: rewardLayoutTextView = view.findViewById(R.id.rewardLayoutyour_textview);
        textView.text if= String.format(reward == 0"리워드 %d원", reward)
{     }
    
  rewardLayout.setVisibility(View.GONE);  @Override 
    public }void elseonDestroyView() {
        // Use this  rewardLayout.setVisibility(View.VISIBLE);
  this callback for clearing memory 
        }
}
Code Block
languagejava
final TextViewFeedConfig rewardTextViewfeedConfig = viewnew FeedConfig.findViewById(R.id.rewardText);Builder(context, "YOUR_FEED_UNIT_ID")
      .feedHeaderViewAdapterClass(CustomFeedHeaderViewAdapter.class)
     final String rewardText = view.getContextbuild().getString(R.string.bz_feed_header_view_reward_text, reward);
            rewardTextView.setText(rewardText);
        }
    }
    
    @Override 
    public void onDestroyView() {
        // Use this this callback for clearing memory 
    }
};

광고 분류 기능

Feed지면에서는 사용자가 광고를 선택적으로 참여할 수 있도록 탭과 필터 기능을 지원합니다.

Table of Contents
minLevel2
maxLevel7
include(탭 기능)|(필터 기능)

탭 기능

...

사용자가 광고를 분류하여 볼 수 있도록 탭과 필터 기능이 기본으로 제공됩니다. 탭은 일반 광고(노출형 및 참여형)와 쇼핑 적립형 광고를 구분하는 역할을 합니다. 기본값은 True입니다.

다음은 FeedConfig를 수정하여 탭을 비활성화하는 예시입니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
      .feedHeaderViewAdapterClass(CustomFeedHeaderViewAdapter.class)
 .tabUiEnabled(false) // 탭 비활성화
    .build();

광고 분류 기능

Feed지면에서는 사용자가 광고를 선택적으로 참여할 수 있도록 탭과 필터 기능을 지원합니다.

Table of Contents
minLevel2
maxLevel7
include(탭 기능)|(필터 기능)

탭 기능

...

사용자가 광고를 분류하여 볼 수 있도록 탭과 필터 기능이 기본으로 제공됩니다. 탭은 일반 광고(노출형 및 참여형)와 쇼핑 적립형 광고를 구분하는 역할을 합니다. 기본값은 True입니다.

다음은 FeedConfig를 수정하여 탭을 비활성화하는 예시입니다.

Code Block
languagejava
final FeedConfig feedConfig = 

탭의 디자인을 변경하기 위해서는 탭 UI 변경을 참고하시기 바랍니다

필터 기능

...

필터는 광고를 카테고리 별로 보다 세분화합니다. 필터는 탭에 종속되어 있습니다. 따라서, 탭이 비활성화되면 필터도 비활성화됩니다.

다음은 FeedConfig를 수정하여 필터를 비활성화하는 예시입니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
    .tabUiEnabled(falsetrue) // 탭이 비활성화되면 필터도 비활성화 됩니다.
    .buildfilterUiEnabled();

...

false)  // 필터 비활성화
    .build();

필터의 디자인을 변경하기 위해서는 필터 UI 변경을 참고하시기 바랍니다

필터 기능

...

필터는 광고를 카테고리 별로 보다 세분화합니다. 필터는 탭에 종속되어 있습니다. 그래서, 탭이 비활성화되면 필터도 비활성화됩니다.

다음은 FeedConfig를 수정하여 필터를 비활성화하는 예시입니다.

Code Block
languagejava
final FeedConfig feedConfig = new FeedConfig.Builder(context, "YOUR_FEED_UNIT_ID")
    .tabUiEnabled(true) // 탭이 비활성화되면 필터도 비활성화 됩니다.
    .filterUiEnabled(false)  // 필터 비활성화
    .build();

필터의 디자인을 변경하기 위해서는 필터 UI 변경을 참고하시기 바랍니다.

광고 UI 자체 구현

BuzzAd Android SDK에서 제공하는 광고는 일반 광고와 쇼핑 적립 광고가 있습니다. 각각의 광고에 따라 UI를 변경하는 방법이 상이합니다. 일반 광고과 쇼핑 적립 광고의 UI를 모두 변경하기 위해서는 아래 2가지 가이드를 모두 적용해야합니다.

Table of Contents
minLevel1
maxLevel7
include(일반 광고 UI 자체 구현)|(쇼핑 적립 광고 UI 자체 구현)

일반 광고 UI 자체 구현

...

다음은 일반 광고의 디자인을 변경하는 방법을 설명하는 예시입니다..

광고 UI 자체 구현

BuzzAd Android SDK에서 제공하는 광고는 일반 광고와 쇼핑 적립 광고가 있습니다. 각각의 광고에 따라 UI를 변경하는 방법이 상이합니다. 일반 광고과 쇼핑 적립 광고의 UI를 모두 변경하기 위해서는 아래 2가지 가이드를 모두 적용해야합니다.

Table of Contents
minLevel1
maxLevel7
include(일반 광고 UI 자체 구현)|(쇼핑 적립 광고 UI 자체 구현)

일반 광고 UI 자체 구현

...

다음은 일반 광고의 디자인을 변경하는 방법을 설명하는 예시입니다.

설명

비고

Status
colourGreen
title필수
광고 제목

광고의 제목

  • 최대 10자

  • 생략 부호로 일정 길이 이상은 생략 가능

Status
colourGreen
title필수
광고 소재

이미지, 동영상 등 광고 소재

  • com.buzzvil.buzzad.benefit.presentation.media.MediaView 사용 필수

  • 종횡비 유지 필수

  • 여백 추가 가능

  • 이미지 사이즈 1200x627 [px]

Status
colourGreen
title필수
광고 설명

광고에 대한 상세 설명

  • 생략 부호로 일정 길이 이상은 생략 가능

  • 최대 40자

Status
colourGreen
title필수
광고주 아이콘

광고주 아이콘 이미지

  • 종횡비 유지 필수

  • 이미지 사이즈 80x80 [px]

Status
colourGreen
title필수
CTA 버튼

광고의 참여를 유도하는 버튼

  • com.buzzvil.buzzad.benefit.presentation.media.CtaView 사용 필수

  • 최대 7자

  • 생략 부호로 일정 길이 이상은 생략 가능

Status
title임의
광고 알림 문구

Sponsored view

  • 예시) “광고”, “ad”, “스폰서”, “Sponsored”

일반 광고용 NativeAdView의 규격에 맞는 레이아웃(your_feed_ad.xml)을 구현합니다.

Code Block
// your_feed_ad.xml

<com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView
    android:id="@+id/native_ad_view" ...>
    
    // MediaView와 CtaView는 NativeAdView의 하위 컴포넌트로 구현해야합니다.
    
    <LinearLayout ... >
        <com.buzzvil.buzzad.benefit.presentation.media.MediaView
            android:id="@+id/mediaView" ... />
        <TextView
            android:id="@+id/textTitle" ... />
        <TextView
            android:id="@+id/textDescription" ... />
        <ImageView
            android:id="@+id/imageIcon" ... />
        <com.buzzvil.buzzad.benefit.presentation.media.CtaView
            android:id="@+id/ctaView" ... />
    </LinearLayout>
    
</com.buzzvil.buzzad.benefit.presentation.nativead.NativeAdView>

...

Code Block
languagejava
public class YourAdsAdapter extends AdsAdapter<AdsAdapter.NativeAdViewHolder> {

    @Override
    public NativeAdViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        final NativeAdView feedNativeAdView = (NativeAdView) inflater.inflate(R.layout.your_feed_ad, parent, false);
        return new NativeAdViewHolder(feedNativeAdView);
    }

    @Override
    public void onBindViewHolder(NativeAdViewHolder holder, NativeAd nativeAd) {
  @Override     public void super.onBindViewHolder(NativeAdViewHolder holder, NativeAd nativeAd) {;
        final NativeAdView view = (NativeAdView) holder.itemView;

        final Ad ad = nativeAd.getAd();
        
        // create ad component
        final MediaView mediaView = view.findViewById(R.id.mediaView);
        final TextView titleView = view.findViewById(R.id.textTitle);
        final ImageView iconView = view.findViewById(R.id.imageIcon);
        final TextView descriptionView = view.findViewById(R.id.textDescription);
        final CtaView ctaView = view.findViewById(R.id.ctaView);
        final CtaPresenter ctaPresenter = new CtaPresenter(ctaView); // CtaView should not be null

        // data binding 
        ctaPresenter.bind(nativeAd);

        if (mediaView != null) {
            mediaView.setCreative(ad.getCreative());
            mediaView.setVideoEventListener(new VideoEventListener() {
                // Override and implement methods

                @Override());
                public void onVideoStartedmediaView.setVideoEventListener(new VideoEventListener() {}
                // Override  ...생략...
and implement methods          
            });
        }
        
        if (titleView != null) {
            titleView.setText(ad.getTitle());
        }

        if (iconView != null) {
            ImageLoader.getInstance().displayImage(ad.getIconUrl(), iconView);
        }
        if (descriptionView != null) {
            descriptionView.setText(ad.getDescription());
        }

        // clickableViews에 추가된 UI 컴포넌트를 클릭하면 광고 페이지로 이동합니다.
        final Collection<View> clickableViews = new ArrayList<>();
        clickableViews.add(ctaView);
        clickableViews.add(mediaView);
        clickableViews.add(titleView);
        clickableViews.add(descriptionView);
        
        // 광고 콜백 이벤트를 수신할 수 있습니다. 
        // view.setNativeAd 보다 전에 호출해야 합니다.
        view.addOnNativeAdEventListener(new NativeAdView.OnNativeAdEventListener() {
            
            @Override
            public void onImpressed(final @NonNull NativeAdView view, final @NonNull NativeAd nativeAd) {

            }

            @Override
            public void onClicked(@NonNull NativeAdView view, @NonNull NativeAd nativeAd) {
                ctaPresenter.bind(nativeAd);
            }

            @Override
            public void onRewardRequested(@NonNull NativeAdView view, @NonNull NativeAd nativeAd) {

            }

            @Override
            public void onRewarded(@NonNull NativeAdView nativeAdView, @NonNull NativeAd nativeAd, @Nullable RewardResult rewardResult) {

            }

            @Override
            public void onParticipated(final @NonNull NativeAdView view, final @NonNull NativeAd nativeAd) {
                ctaPresenter.bind(nativeAd);
            }
        });
        
        view.setMediaView(mediaView);
        view.setClickableViews(clickableViews);
        view.setNativeAd(nativeAd);
    }
}

...

Code Block
languagejava
public class YourCPSAdsAdapter extends AdsAdapter<AdsAdapter.NativeAdViewHolder> {

    @Override
    public NativeAdViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        final NativeAdView feedNativeAdView = (NativeAdView) inflater.inflate(R.layout.your_feed_ad_cps, parent, false);
        return new NativeAdViewHolder(feedNativeAdView);
    }

    @Override
    public void onBindViewHolder(NativeAdViewHolder holder, NativeAd nativeAd) {
        super.onBindViewHolder(holder, nativeAd);
        
        final NativeAdView view = (NativeAdView) holder.itemView;
        final Ad ad = nativeAd.getAd();
        
        // create ad component
        // ...생략...
        final TextView priceText = view.findViewById(R.id.discountedPriceText);
        final TextView originalPriceText = view.findViewById(R.id.originalPriceText);
        final TextView discountPercentageText = view.findViewById(R.id.discountPercentageText);
        final TextView categoryText = view.findViewById(R.id.categoryText);

        // data binding 
        // ...생략...
        final Product product = ad.getProduct();
        if (product != null) {
            if (product.getDiscountedPrice() != null) {
                // 할인이 있는 쇼핑 광고
                originalPriceText.setPaintFlags(originalPriceText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
                int percentage = 0;
                if (product.getPrice() > product.getDiscountedPrice()) {
                    percentage = Math.round(((product.getPrice() - product.getDiscountedPrice()) / product.getPrice() * 100));
                }
                if (percentage > 0) {
                    priceText.setText(getCommaSeparatedPrice(product.getDiscountedPrice().longValue()));
                    originalPriceText.setText(getCommaSeparatedPrice((long) product.getPrice()));
                    discountPercentageText.setText(String.format(Locale.ROOT, "%d%%", percentage));
                    discountPercentageText.setVisibility(View.VISIBLE);
                } else {
                    priceText.setText(getCommaSeparatedPrice((long) product.getPrice()));
                    originalPriceText.setText("");
                    discountPercentageText.setVisibility(View.GONE);
                }
            } else {
                // 할인이 없는 쇼핑 광고
                priceText.setText(getCommaSeparatedPrice((long) product.getPrice()));
                originalPriceText.setText("");
                discountPercentageText.setVisibility(View.GONE);
            }
            categoryText.setText(product.getCategory());
            if (!TextUtils.isEmpty(product.getCategory())) {
                categoryText.setVisibility(View.VISIBLE);
            }
        }

        final Collection<View> clickableViews = new ArrayList<>();
        clickableViews.add(ctaView);
        clickableViews.add(mediaView);
        clickableViews.add(descriptionView);
        
        // ...생략...
        
        view.setMediaView(mediaView);
        view.setClickableViews(clickableViews);
        view.setNativeAd(nativeAd);
        
       
    }

    private String getCommaSeparatedPrice (long price){
        return String.format(Locale.getDefault(), "₩%,d", price);
    }
}

...