Standard Pop
Learn how to add Standard Pop, implement its features and customize icons and other design elements.
Key features
Standard Pop is a circular button outside your app that directs users to BuzzBenefit. It appears whenever users unlock their screen and can be dragged to another position. It uses transparency to accommodate Android 12's restrictions on touch events through overlays and keep the app working reliably.

Integration
Follow these steps to add Standard Pop.
Step 1. Prepare
- Complete BuzzBenefit integration.
- Add the Pop dependency to your Gradle file.
dependencies {
def buzzvilBomVersion = 5.36.+
api platform("com.buzzvil:buzzvil-bom:$buzzvilBomVersion")
implementation "com.buzzvil:buzzad-benefit-pop"
}
Step 2. Add Pop BuzzBenefit
BuzzBenefit opened through Pop can reuse your existing integration without a separate ID. Follow these steps to add it.
- Create a new
FeedConfigand set the Unit ID to use for the Pop BuzzBenefit ID (YOUR_POP_UNIT_ID). - Set
optInFeatureListon theFeedConfigyou created.
- The
FeedConfigsettings also apply to Pop BuzzBenefit. See BenefitHub and UI settings — BenefitHub for details aboutFeedConfig.
import com.buzzvil.buzzad.benefit.BuzzAdBenefitConfig
import com.buzzvil.buzzad.benefit.presentation.feed.FeedConfig
import com.buzzvil.buzzad.benefit.presentation.feed.config.OptInFeature
import com.buzzvil.sdk.BuzzvilSdk
val feedConfig = FeedConfig.Builder("YOUR_POP_UNIT_ID")
.optInFeatureList(mutableListOf(OptInFeature.Pop))
.build()
val buzzAdBenefitConfig = BuzzAdBenefitConfig.Builder(context)
.setDefaultFeedConfig(feedConfig)
.build()
BuzzvilSdk.initialize(this@App, buzzAdBenefitConfig)
Step 3. Enable Pop
Follow these steps to enable Pop for users.
- Call
BuzzAdPop.activate()to enable Pop.
- Android 6.0 Marshmallow and later require permission to draw over other apps. Prompt for this permission as needed when calling
BuzzAdPop.activate().
-
Display the Pop button with
BuzzAdPop.getInstance().show().import com.buzzvil.buzzad.benefit.pop.BuzzAdPop BuzzAdPop.getInstance().activate(object: BuzzAdPop.PopActivateListener { override fun onActivated() { // 정상적으로 Pop이 활성화 되었을 때 호출됩니다. // 유저 화면에 바로 Pop을 표시합니다. BuzzAdPop.getInstance().show() } override fun onActivationFailed(error: Throwable?) { // Pop 활성화에 실패하였을 때 호출됩니다. } })
Disable Pop
Call buzzAdPop.deactivate(Context) to disable Pop. The foreground service notification also disappears.
The following example disables Pop.
import com.buzzvil.buzzad.benefit.pop.BuzzAdPop
BuzzAdPop.getInstance().deactivate(context)
Additional features
Learn how to implement and configure the Pop button and Pop BenefitHub. The main features are shown below.

Configure PopConfig
Use PopConfig to manage Pop BenefitHub with a separate Unit ID or configure features beyond those set through FeedConfig.
The following example adds PopConfig to BuzzAdBenefitConfig.
import com.buzzvil.buzzad.benefit.BuzzAdBenefitConfig
import com.buzzvil.buzzad.benefit.pop.PopConfig
import com.buzzvil.buzzad.benefit.presentation.feed.FeedConfig
import com.buzzvil.sdk.BuzzvilSdk
val popFeedConfig = FeedConfig.Builder(Constant.YOUR_POP_ID)
.build()
val popConfig = PopConfig.Builder(popFeedConfig)
.build()
// BuzzBenefit 설정
val buzzAdBenefitConfig = BuzzAdBenefitConfig.Builder(Constant.YOUR_APP_ID)
.setPopConfig(popConfig)
.build()
// Buzzvil SDK 초기화
BuzzvilSdk.initialize(
application = this@App,
buzzAdBenefitConfig = buzzAdBenefitConfig
)
Change the Pop button display duration
Set how long the Pop button remains visible before disappearing. The default is 5 seconds.
import com.buzzvil.buzzad.benefit.pop.PopConfig
val popConfig = PopConfig.Builder(popFeedConfig)
.idleTimeInMillis(5000) // Pop 표시 시간
.build()
Change the Pop button position
Set where the button appears when users unlock their device. The default is SidePosition.Side.RIGHT, 0.6f, on the right side at 60% of the screen height measured from the top (SidePosition.Side.LEFT / SidePositionSide.RIGHT).
import com.buzzvil.buzzad.benefit.pop.PopConfig
import com.buzzvil.buzzad.benefit.pop.popicon.SidePosition
val popConfig = PopConfig.Builder(popFeedConfig)
.initialSidePosition(SidePosition(SidePosition.Side.RIGHT, 0.6f)) // Pop 표시 위치
.build()
Set Pop button horizontal spacing
Set the space between Pop and its preview view on the left, and between Pop and the right screen edge. The defaults are 8dp between the button and message, and 0dp between the button and screen edge.
import com.buzzvil.buzzad.benefit.pop.PopConfig
val popConfig = PopConfig.Builder(popFeedConfig)
.marginBetweenIconAndPreviewInDp(8.0f) // 팝 버튼과 메시지 사이 간격
.marginBetweenIconAndScreenEdgeInDp(24.0f) // 팝 버튼과 화면 끝 사이 간격
.build()
Implement a custom Pop foreground service notification
Use PopConfig to implement your own notification behavior and layout.
Enabling Pop starts its foreground service notification. Unless you customize it with PopConfig, the SDK's default notification appears in the device notification panel.

Follow these steps to implement a custom Pop foreground service notification.
- Implement a subclass of
PopControlService.
-
Create
notificationChannelor register a View. -
Use
getPopPendingIntent(unitId, context)to obtain aPendingIntentthat opens Pop.The following example implements a subclass of
PopControlService.import android.annotation.TargetApi import android.os.Build import android.widget.RemoteViews import androidx.core.app.NotificationCompat import com.buzzvil.buzzad.benefit.pop.PopControlService import com.buzzvil.buzzad.benefit.pop.PopNotificationConfig class YourPopControlService: PopControlService() { companion object { const val POP_NOTIFICATION_ID = "1000" } override fun buildForegroundNotification(unitId: String, popNotificationConfig: PopNotificationConfig): Notification { // Pop을 표시하는 PendingIntent (원형 아이콘) val popPendingIntent = getPopPendingIntent(unitId, this) // 필요에 따라 notificationChannel을 등록합니다. val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannelIfNeeded() NotificationCompat.Builder(this, POP_NOTIFICATION_ID) } else { NotificationCompat.Builder(this) } // Pop Service Notification에 사용할 View 를 등록합니다. val remoteView = RemoteViews(packageName, R.layout.notification_pop) builder.setSmallIcon(popNotificationConfig.smallIconResId) .setContent(remoteView) .setContentIntent(popPendingIntent) .setPriority(NotificationCompat.PRIORITY_LOW) .setShowWhen(false) builder.foregroundServiceBehavior = NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE if (popNotificationConfig.color != null) { builder.color = popNotificationConfig.color!! } return builder.build() } @TargetApi(Build.VERSION_CODES.O) override fun createNotificationChannelIfNeeded() { val notificationManager = getSystemService(NOTIFICATION_SERVICE) as android.app.NotificationManager if (notificationManager.getNotificationChannel(POP_NOTIFICATION_ID) == null) { val channel = android.app.NotificationChannel( POP_NOTIFICATION_ID, NOTIFICATION_CHANNEL_NAME, android.app.NotificationManager.IMPORTANCE_LOW ) notificationManager.createNotificationChannel(channel) } } } -
Set
notificationIdon thePopNotificationConfigobject, as shown below.import com.buzzvil.buzzad.benefit.BuzzAdBenefitConfig import com.buzzvil.buzzad.benefit.pop.PopConfig import com.buzzvil.buzzad.benefit.pop.PopNotificationConfig import com.buzzvil.buzzad.benefit.presentation.feed.FeedConfig // PopNotificationConfig 설정 val popNotificationConfig = PopNotificationConfig.Builder(this@App) .notificationId(YourPopControlService.POP_NOTIFICATION_ID) .build() // Pop을 Feed와 분리하여 따로 설정 val popFeedConfig = FeedConfig.Builder(Constant.YOUR_POP_ID) .build() val popConfig = PopConfig.Builder(popFeedConfig) .popNotificationConfig(popNotificationConfig) .controlService(YourPopControlService::class.java) .build() // BuzzBenefit 설정 val buzzAdBenefitConfig = BuzzAdBenefitConfig.Builder(Constant.YOUR_APP_ID) .setPopConfig(popConfig) .build()
- Register your subclass as
serviceinAndroidManifest.xml.
```xml
<application>
<service android:name=".YourControlService"
android:foregroundServiceType="specialUse">
<property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="floating bubble for user to interact" />
</service>
</application>
```
Implement a custom navigation bar
Customize the Pop BenefitHub navigation bar using either the SDK's default UI or your own custom view.

Use the SDK's default UI
Modify the SDK's default UI to customize the Pop BenefitHub navigation bar.

Implement a subclass of DefaultPopToolbarHolder and customize the layout using the default PopToolbar UI. Register your class in popToolbarHolderClass of PopConfig.
The following example implements a Pop BenefitHub navigation bar using the SDK's UI.
import com.buzzvil.buzzad.benefit.pop.toolbar.DefaultPopToolbarHolder
import com.buzzvil.buzzad.benefit.pop.toolbar.PopToolbar
class YourPopToolbarHolder : DefaultPopToolbarHolder() {
override fun getView(activity: Activity, unitId: String): View {
super.toolbar = PopToolbar(activity) // PopToolbar 에서 제공하는 기본 Template 사용
toolbar.setTitle("TemplatePopToolbarHolder") // 내비게이션 바 타이틀 문구를 변경합니다.
toolbar.setIconResource(R.mipmap.ic_launcher) // 내비게이션 바 좌측 아이콘을 변경합니다.
toolbar.setBackgroundColor(Color.LTGRAY) // 내비게이션 바 배경색을 변경합니다.
addSettingsMenuItemView(activity) // 메뉴 버튼 추가 (메뉴 안에 문의하기 버튼이 있습니다)
addInquiryMenuItemView(activity) // 문의하기 버튼은 이 함수를 통해 간단하게 추가 가능합니다.
addRightMenuItemView(activity) // custom 버튼 추가
return toolbar
}
// custom 버튼 추가는 toolbar.buildPopMenuItemView 를 사용하여 PopMenuImageView 를 생성하고
// toolbar.addRightMenuButton 를 사용하여 toolbar 에 추가합니다.
private fun addRightMenuItemView(activity: Activity) {
val menuItemView = super.toolbar.buildPopMenuItemView(activity, R.mipmap.ic_launcher)
menuItemView.setOnClickListener {
super@YourPopToolbarHolder.showInquiry(activity) // 문의하기 페이지로 연결합니다.
}
toolbar.addRightMenuButton(menuItemView)
}
}
Set YourPopToolbarHolder on PopConfig.
import com.buzzvil.buzzad.benefit.pop.PopConfig
import com.buzzvil.buzzad.benefit.presentation.feed.FeedConfig
val popFeedConfig = FeedConfig.Builder("YOUR_POP_UNIT_ID")
.build()
PopConfig.Builder(popFeedConfig)
.popToolbarHolderClass(YourPopToolbarHolder::class.java)
.build()
Use your own custom view
Implement a custom view instead of the SDK's UI to replace the Pop BenefitHub navigation bar.

The following example subclasses DefaultPopToolbarHolder to create a custom navigation bar view, then registers the class in PopConfig.
import android.app.Activity
import android.graphics.Color
import android.view.View
import com.buzzvil.buzzad.benefit.pop.toolbar.DefaultPopToolbarHolder
import com.buzzvil.buzzad.benefit.pop.toolbar.PopToolbar
class CustomPopToolbarHolder: DefaultPopToolbarHolder() {
override fun getView(activity: Activity, unitId: String): View {
super.toolbar = PopToolbar(activity) // PopToolbar에서 제공하는 기본 Template 사용
toolbar.setTitle("Custom Title") // 내비게이션 바 타이틀 문구를 변경합니다.
toolbar.setIconResource(R.mipmap.ic_launcher) // 내비게이션 바 좌측 아이콘을 변경합니다.
toolbar.setBackgroundColor(Color.LTGRAY) // 내비게이션 바 배경색을 변경합니다.
super.addSettingsMenuItemView(activity) // 메뉴 버튼 추가 (메뉴 안에 문의하기 버튼이 있습니다)
super.addInquiryMenuItemView(activity) // 문의하기 버튼은 이 함수를 통해 간단하게 추가 가능합니다.
addRightMenuItemView(activity) // custom 버튼 추가
return toolbar
}
// custom 버튼 추가는 toolbar.buildPopMenuItemView 를 사용하여 PopMenuImageView 를 생성하고
// toolbar.addRightMenuButton 를 사용하여 toolbar 에 추가합니다.
private fun addRightMenuItemView(activity: Activity) {
val menuItemView = toolbar.buildPopMenuItemView(activity, R.drawable.ic_launcher_foreground)
menuItemView.setOnClickListener {
super.showInquiry(activity) // 문의하기 페이지로 연결합니다.
}
toolbar.addRightMenuButton(menuItemView)
}
}
import com.buzzvil.buzzad.benefit.pop.PopConfig
import com.buzzvil.buzzad.benefit.presentation.feed.FeedConfig
val popFeedConfig = FeedConfig.Builder("YOUR_POP_UNIT_ID")
.build()
PopConfig.Builder(popFeedConfig)
.popToolbarHolderClass(CustomPopToolbarHolder::class.java)
.build()
Customize the Pop utility area
Add features such as opening an app menu or navigating to another page in the utility area at the lower right of Pop.

The following example extends PopUtilityLayoutHandler, adds a custom view (your_pop_utility_view), then registers the class in FeedConfig.
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.buzzvil.buzzad.benefit.pop.feedutility.PopUtilityLayoutHandler
class CustomPopUtilityLayoutHandler(val context: Context): PopUtilityLayoutHandler(context) {
override fun onCreateView(parent: ViewGroup?): View {
val inflater = LayoutInflater.from(context)
return inflater.inflate(R.layout.your_pop_utility_view, parent, false)
}
}
import com.buzzvil.buzzad.benefit.pop.PopConfig
import com.buzzvil.sample.buzzvilsdksample.pop.CustomPopUtilityLayoutHandler
PopConfig.Builder(popFeedConfig)
.popUtilityLayoutHandlerClass(CustomPopUtilityLayoutHandler::class.java)
.build()
Utility icon specifications
Use the following image specifications for icons in the utility area.
| Item | Specification |
|---|---|
| Image type | Raster or vector image |
| Size |
|
| Color | Monochrome or full color |
Add a custom page
Add a fully customized Pop BenefitHub page with a navigation bar and content area. Set a title in the navigation bar and a Fragment of your choice in the content area.

Add the following code when implementing the default Pop BenefitHub navigation bar or customizing the utility area.
import com.buzzvil.buzzad.benefit.pop.navigation.CustomInAppLandingInfo
import com.buzzvil.buzzad.benefit.pop.navigation.PopNavigator
PopNavigator().launchCustomFragment(
context,
CustomInAppLandingInfo(
YourFragment(),
R.string.your_title
)
)
UI configuration
Learn how to customize the Pop button and placement UI. See the Pop design guide for detailed Pop BenefitHub specifications.
For further customization, implement your own placement following Standard Pop additional features.
Pop button color
Use GlobalTheme, which controls the primary UI color, to change the Pop button color. See Global theme.

Pop button icons
Set BuzzAdPopTheme in Application.onCreate to change the default, reward and close icons.

| Icon type | Code | Description | Recommended size |
|---|---|---|---|
| Default icon | iconResId | The default Pop button icon. |
|
| Reward icon | rewardReadyIconResId | Shown when points are available to earn. |
|
| Close icon | popFeedCloseIconResId | Closes Pop BenefitHub. |
|
The following example changes Pop icons.
import com.buzzvil.buzzad.benefit.pop.BuzzAdPop
import com.buzzvil.buzzad.benefit.pop.BuzzAdPopTheme
val buzzAdPopTheme = BuzzAdPopTheme.getDefault()
// ...생략...
.iconResId(R.drawable.your_pop_icon)
.rewardReadyIconResId(R.drawable.your_pop_icon_reward_ready)
.popFeedCloseIconResId(R.drawable.your_pop_icon_feed_close)
BuzzAdPop.getInstance().setTheme(buzzAdPopTheme)
Configure Pop button icon resources
Configure the icon resources as follows.
iconResId: Specify the default and close icons.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_pop_selected" android:state_selected="true" />
<item android:drawable="@drawable/icon_pop"/>
</selector>
rewardReadyIconResId: Specify the icon shown when points are available to earn.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_pop_selected" android:state_selected="true" />
<item android:drawable="@drawable/icon_pop_reward_ready"/>
</selector>
Pop foreground service notification
When Pop is enabled, its foreground service notification appears in the device notification panel. Customize its design using the SDK's default UI settings.
The diagram and table below show which notification elements you can customize.

| Number | Component | Description |
|---|---|---|
| 1 | Small icon (smallIconResId) | Your app's icon. ❗️ Caution: Adaptive Icons are not recommended because they may not display correctly. |
| 2 | Color (colorResId) | Color applied to the app icon and name. ❗️ Caution: Avoid white, which matches the notification background. |
| 3 | Title (titleResId) | Text identifying the Pop foreground service notification. |
| 4 | Text (textResId) | Text explaining that tapping the notification opens Pop BenefitHub. |
Configure the elements in PopNotificationConfig, then set popNotificationConfig on popFeedConfig to apply the notification design.
The following example customizes the Pop foreground service notification.
import com.buzzvil.buzzad.benefit.pop.PopNotificationConfig
val popNotificationConfig = PopNotificationConfig.Builder(applicationContext)
.smallIconResId(R.drawable.your_small_icon) // 흰색 아이콘, Adaptive Icon 이 설정하지 않도록 주의 요망
.titleResId(R.string.your_pop_notification_title)
.textResId(R.string.your_pop_notification_text)
.colorResId(R.color.your_pop_notification_color)
.notificationId(5000) // 기본값
.build()
import com.buzzvil.buzzad.benefit.pop.PopConfig
import com.buzzvil.buzzad.benefit.presentation.feed.FeedConfig
val popFeedConfig = FeedConfig.Builder("YOUR_POP_UNIT_ID").build()
val popConfig = PopConfig.Builder(popFeedConfig)
// ...생략...
.popNotificationConfig(popNotificationConfig)
.build()
Navigation bar icon color
Change the left-hand navigation bar icon color in Pop BenefitHub. See Global theme.

Pop message area
When ads are available in Pop BenefitHub, PopAdMessageViewClass displays a message bubble (preview). The default class lets you configure the available points and remaining display time in seconds.

Follow these steps to change the Pop message area.
- Override the following functions in
PopAdMessageViewClass.
- Implement
PopAdMessageViewClassby extendingPopAdMessageView.
| Function | Description |
|---|---|
updateView | Called every second when the message bubble updates. Receives the remaining seconds and available reward as arguments. |
getDurationInSeconds | Return the Pop display duration in seconds. The recommended duration is 5 seconds. |
See the following code example.
import android.content.Context
import android.view.LayoutInflater
import android.widget.TextView
import com.buzzvil.buzzad.benefit.pop.message.PopAdMessageView
class CustomPopAdMessageView: PopAdMessageView {
private lateinit var textTitle: TextView
private lateinit var textDescription: TextView
constructor(context: Context): super(context) {
val view = LayoutInflater.from(context).inflate(R.layout.your_pop_ad_message_view, this)
this.textTitle = view.findViewById(R.id.textTitle)
this.textDescription = view.findViewById(R.id.textDescription)
}
override fun updateView(reward: Int, remainSeconds: Int) {
textTitle.text = "$reward 포인트 적립 가능합니다."
textDescription.text = "$remainSeconds 초 후에 닫힙니다."
}
override fun getDurationInSeconds(): Int {
return 5
}
override fun getMessage(): String {
return textTitle.text.toString()
}
}
- Apply the following code to use Pop with your updated message area.
import com.buzzvil.buzzad.benefit.pop.PopConfig
PopConfig.Builder(applicationContext, "POP_UNIT_ID")
.popAdMessageViewClass(CustomPopAdMessageView::class.java)