Buzzscreen
BuzzScreen 과 같이 연동하고 있는 경우 com.android.tools.r8.errors.CompilationError: Program type already present: com.buzzvil.buzzresource.BuildConfig
에러가 발생 할 수 있으며 BuzzScreen 3.11.+ 연동 시 해결됩니다.
Build
빌드할 때 다음과 같은 문제가 발생한 경우
Warning: com.buzzvil.buzzad.benefit.pop.PopControlService: can't find referenced method 'android.view.DisplayCutout getCutout()' in library class android.view.Display
compileSdkVersion 을 29 이상으로 변경하거나,
proguard rules 에 -dontwarn android.view.Display 를 추가
com.android.tools.r8.errors.CompilationError: Program type already present: com.buzzvil.buzzresource.BuildConfig
Buzzscreen SDK와 같이 연동하고 있는 경우 Buzzscreen SDK 3.11.+ 연동 시 해결됩니다.
java.lang.RuntimeException: Unable to start activity ComponentInfo{…/com.buzzvil.buzzad.browser.BuzzAdBrowserActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
BuzzAdBrowserActivity에 theme 설정이 되어있지 않아, 전역으로 설정된 theme이 맞지 않을 경우 문제가 발생 (수정 예정)
AppCompat Theme중 하나를 상속받는 theme을 styles.xml에 정의
<style name="CustomTheme" parent="Theme.AppCompat.DayNight"> <!-- add your custom attributes here --> </style>
AndroidManifest.xml에 다음 line을 추가
<activity android:name="com.buzzvil.buzzad.browser.BuzzAdBrowserActivity" android:theme="@style/CustomTheme" tools:replace="android:theme"/>
광고 할당
BuzzAdBenefit SDK는 광고를 받아오고 보여주는 역할을 합니다. 이때 유저 정보가 없다면 광고 할당을 받을 수 없기 때문에 반드시 유저 정보를 SDK에 등록하는 과정이 필요합니다. 그 과정은 여기에서 진행하실 수 있습니다.
setUserProfile
를 통해 유저 정보를 SDK에 등록하면 내부적으로 세션키를 발급 하는데 이는 광고 할당에 꼭 필요한 값입니다. 만약 setUserProfile
이후 짧은 시간 안에 광고 할당 요청을 하면 세션키 발급이 완료되지 않아 요청이 실패할 수 있습니다. 이런 경우에 다음과 같이 세션이 발급이 완료되었는지 확인할 수 있는 receiver를 등록하여 확인 후 광고 할당 요청을 보낼 수 있습니다.
// 1. create a BroadcastReceiver private BroadcastReceiver sessionReadyReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Session is ready } }; // 2. register the receiver to LocalBroadcastManager private void registerSessionReadyReceiver() { LocalBroadcastManager.getInstance(context).registerReceiver(sessionReadyReceiver, BuzzAdBenefit.getSessionReadyIntentFilter()); } // 3. unregister the receiver when you're done private void unregisterSessionReadyReceiver() { LocalBroadcastManager.getInstance(context).unregisterReceiver(sessionReadyReceiver); }
액션형 광고 주의 사항
BuzzAd Benefit SDK는 비디오, 앱 인스톨, 페이스북 페이지 좋아요 등 다양한 유저 액션에 리워드를 지급하는 광고를 제공 하며 이를 액션형 광고로 칭합니다.
액션형 광고 참여 단계에 따른 CTA 변화
액션형 광고는 참여 전, 참여 확인 중, 참여 완료의 세가지 상태를 가지는데, CTA 버튼에 해당 상태 변화 적용해야 합니다.
2.2.3 버전 미만 버전에만 해당합니다.
이전 버전으로 연동을 했었고, CTA 버튼을 custom class 로 구현하여 사용하고 있었다면, 아래의 변경 사항을 참고하여 모든 상황에서 CTA 가 정상적으로 보일 수 있게 적용하는 것을 권장합니다. (CTA 버튼 구현은, 광고지면 타입에서 다룹니다.)
(기존) 액션형 광고의 경우, 포인트 적립 시점이 광고 클릭 시점과 다르기 때문에 CTA 를 '적립 완료'로 표시할 수 없었습니다. 광고 클릭이 확인되는 시점에 '참여 확인 중' 으로 변경하여 사용하고 있었습니다.
(변경) 액션형 광고도 노출형과 같이, 적립 완료 콜백이 적용 됩니다. 참여 전 → 참여 확인 중 (is clicked) → 참여 완료 (is participated) 의 단계로 구분되어야 합니다.
액션형 광고에 대한 유저 VOC (문의하기) 사용하기
액션형 광고의 경우 종종 리워드 미적립을 이유로 유저가 문의(VOC)를 보내기도 합니다.
이러한 유저 VOC에 대한 접수 및 처리를 자동화 하기 위해 SDK에서는 미리 만들어 놓은 웹 페이지를 제공하고 있습니다. 이 문의하기 페이지는 연동되어 있는 앱을 기준으로 조회하기 때문에, 유닛별로 구현할 필요가 없으며, VOC의 위치를 강제하지 않습니다.
아래의 단계를 통해 해당 기능을 사용하실 수 있습니다.
VOC 페이지 로드를 위한 유저 진입 Icon/ Tab을 디자인 합니다.
1번의 Icon/Tab이 클릭될 때 코드에서
BuzzAdBenefit.getInstance().showInquiryPage(context)
호출합니다.특정 유닛에 대해서만 문의하기 페이지를 보여주고 싶은 경우,
showInquiryPage(Context context, @Nullable final String unitId)
을 사용할 수 있습니다. 보여주고 싶은 지면의 Unit Id 를 입력하여 사용할 수 있으며, Unit Id 가 null 로 들어올 경우 앱 기준으로 조회할 수 있습니다.
Interstitial, Feed 타입의 경우, 문의하기에 사용하는 기본 제공 아이콘을 사용하실 수 있습니다. (아래를 클릭하여 이미지 및 적용 방법을 확인할 수 있습니다.)
Custom In-App Browser 사용법
현재 Custom Launcher 를 사용하지 않을 경우 아래 가이드는 아무 영향이 없습니다.
Custome Launcher 사용할 예정이거나, 1.X 버전에서 이미 사용하고 있을 경우, 아래의 항목을 필수로 적용해야 합니다.
Custom launcher 사용시, 광고를 클릭했을 때 랜딩되는 In-App Browser를 Customize 할 수 있습니다. 예를 들어, 광고 랜딩 페이지 로드 등을 매체사가 지정하는 Class에서 구현할 수 있습니다.
구현시 주의사항 :
BuzzAdBrowser에서 제공하는 Fragment를 사용하여 In-App Browser를 구현해야 합니다. 사용하지 않을 경우, 일부 광고(액션형 광고, 체류 리워드 광고)가 제대로 동작하지 않을 수 있습니다.
Launcher에서 제공하는 LandingInfo 의 URL을 임의로 변경해서 사용하면 안됩니다. 이 경우 웹 페이지가 제대로 로드되지 않을 수 있습니다.
[1] CustomBrowserActivity
를 구현합니다.
public class CustomBrowserActivity extends AppCompatActivity { public static final String KEY_URL = "com.sample.KEY_URL"; private BuzzAdWebView webView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_browser); // URL을 KEY로 하여 WebView를 가지고있는 Fragment를 받아와 사용합니다. Intent intent = getIntent(); BuzzAdBrowserFragment fragment = BuzzAdBrowser.getInstance(this).getFragment(intent.getStringExtra(KEY_URL)); getSupportFragmentManager().beginTransaction().replace(R.id.browserContainer, fragment).commit(); this.webView = fragment.getWebView(); // Browser의 이벤트를 받을 수 있습니다. DeepLink가 열렸을 경우, Browser를 닫아주어야 빈 페이지가 보여지는 현상을 방지할 수 있습니다. BuzzAdBrowser.getInstance(this).setOnBrowserEventListener(new BuzzAdBrowser.OnBrowserEventListener() { // 기존에 사용하던 isDeepLink 를 아래로 대체 @Override public void onDeepLinkOpened() { finish(); } }); } // Optional - BackButton을 눌렀을때 뒤로가기 기능 @Override public void onBackPressed() { if (webView.canGoBack()) { webView.goBack(); } else { super.onBackPressed(); } } }
[2] activity_custom_browser.xml
?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/browserContainer" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
[3] Launcher
를 구현
public class MyLauncher implements Launcher { @Override public void launch(@NonNull Context context, @NonNull LaunchInfo launchInfo) { launch(context, launchInfo, null); } @Override public void launch(@NonNull final Context context, @NonNull final LaunchInfo launchInfo, @Nullable final LauncherEventListener listener) { launch(context, launchInfo, listener, null); } @Override public void launch(@NonNull final Context context, @NonNull final LaunchInfo launchInfo, @Nullable final LauncherEventListener listener, @Nullable List<Class<? extends BuzzAdJavascriptInterface>> javascriptInterfaces) { // Custom Browser 실행 final Intent intent = new Intent(context, CustomBrowserActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putString(CustomBrowserActivity.KEY_URL, launchInfo.getUri().toString()); // URI는 변경 하면 안 됨 context.startActivity(intent); } }
[4] BuzzAdBenefit.init
호출 이후에 생성한 Launcher
를 세팅
BuzzAdBenefit.setLauncher(new MyLauncher());
[+] Custom launcher 사용시 Article의 sourceUrl 사용법
public class MyLauncher implements Launcher { @Override public void launch(@NonNull final Context context, @NonNull final LaunchInfo launchInfo, @Nullable final LauncherEventListener listener, @Nullable List<Class<? extends BuzzAdJavascriptInterface>> javascriptInterfaces) { if (launchInfo.getArticle() != null) { String sourceUrl = launchInfo.getArticle().getSourceUrl(); } } }
컨텐츠의 경우 url scheme에 따라 랜딩 방식을 다르게 처리하고 싶다면 (ex. 앱 안에서 브라우저 오픈 없이 다른 화면으로 이동되는 컨텐츠) 다음과 같은 방법으로 NativeArticle
객체의 sourceUrl
을 가져와 분기 처리를 할 수 있습니다.
[+] Custom launcher 사용시 광고 또는 컨텐츠인지 미리 판단하고 싶을 경우
public class MyLauncher implements Launcher { ... @Override public void launch(@NonNull final Context context, @NonNull final LaunchInfo launchInfo, @Nullable final LauncherEventListener listener, @Nullable List<Class<? extends BuzzAdJavascriptInterface>> javascriptInterfaces) { // 광고 또는 컨텐츠인지 미리 판단하고 싶을 경우, 다음을 이용하여 확인 if (launchInfo.getAd() != null) { // 광고 } else if (launchInfo.getArticle() != null) { // 컨텐츠 } ...// Custom Browser 실행 } }