Native Advertisements
Natural advertising tailored to the service UI is available through native ads.
Ad properties such as title, image, and call-to-action buttons are provided, allowing the creation of a custom UI.
Before Starting
-
Ad Unit ID is required for ad calling.
Please complete the settings for advertising provider, inventory, and registering of ad units through the NAM Admin.
Please contact the NAM manager for related inquiries.
-
If there are other Views at the top of the ad, the exposure measurement may not be performed properly, resulting in a disadvantage in measuring performance indicators.
[Step 1] Integrate NAM SDK
Please refer to common integration details..
The following steps will assume that the NAM SDK application has been completed.
[Step 2] Layout configuration
To display a native ad, it is necessary to add the ViewGroup in which the native ad will be inserted to the Activity or Fragment layout. This layout will be the ad location.
In the example below, a native ad declared a ViewGroup in the RelativeLayout ViewGroup with the ID native_container
.
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".NativeBannerFragment">
<RelativeLayout
android:id="@+id/native_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
[Step 3] GfpNativeAdView layout configuration
Once the layout including the ViewGroup
where native ads will be displayed has been configured, the layout for rendered native ads needs to be configured.
Assume that the xml file reflecting the required below precautions is named content_native_ad.xml
.
This layout is used in the rendering step after the loading is complete.
- The uppermost layout should be
com.naver.gfpsdk.GfpNativeAdView
. - A ViewGroup to contain assets must be assigned under
GfpNativeAdView
.- In the example below, the ID was declared with assets_container.
- This ViewGroup will be included as a child of the required layout of the ad provider that will attempt rendering. Therefore, it must be assigned.
GfpAdChoicesView
whereAdChoicesView
is rendered must be assigned.- AdChoicesView of FAN and S2S advertisements is rendered in this area.
- Assets must be allocated under ViewGroup, which is a container.
- The width and height values must be 20dp or higher. The recommended width is wrap_content and the height is wrap_content.
- Native ads must be displayed according to the Interactive Advertising Bureau (IAB). Reference - Google Guide
- The main image or video section that is not an icon must be declared as
GfpMediaView
. - When rendering
Native Banner
ads, theGfpMediaView
does not need to be declared.
<?xml version="1.0" encoding="utf-8"?>
<com.naver.gfpsdk.GfpNativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gfp_native_ad"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:id="@+id/assets_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#FFFFFF"
android:minHeight="50dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_marginRight="10dp"
android:adjustViewBounds="true" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:ellipsize="end"
android:lines="1"
android:textColor="#000000"
android:textSize="12dp" />
<TextView
android:id="@+id/ad_sponsored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/ad_attribution"
android:textColor="#999999"
android:textSize="12dp" />
</LinearLayout>
<com.naver.gfpsdk.GfpAdChoicesView
android:id="@+id/ad_choices_view"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/ad_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#000000"
android:textSize="15dp" />
<!--
if there is no media view
new GfpNativeAdOptions.Builder().setHasMediaView(false)
this should be deleted
-->
<com.naver.gfpsdk.GfpMediaView
android:id="@+id/ad_media"
android:layout_width="match_parent"
android:layout_height="220dp"
android:layout_marginBottom="12dp"
android:adjustViewBounds="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical">
<TextView
android:id="@+id/ad_advertiser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:textColor="@android:color/darker_gray"
android:textSize="13dp" />
<TextView
android:id="@+id/ad_social_context"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center_vertical"
android:lines="1"
android:textColor="@android:color/black"
android:textSize="13dp" />
</LinearLayout>
<Button
android:id="@+id/ad_call_to_action"
android:layout_width="100dp"
android:layout_height="40dp"
android:background="@color/colorPrimary"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:textColor="#ffffff"
android:textSize="13dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</com.naver.gfpsdk.GfpNativeAdView>
[Step 4] Create AdParam and GfpAdLoader
Create GfpAdLoader
to request native ads.
An AdParam
object containing the ad request information is created and assigned to the GfpAdLoader
creator.
Request information other than the Ad Unit ID
is optional. Please refer to the ad request information.
- Kotlin
- Java
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_native_banner, container, false)
val nativeContainer = view.findViewById<RelativeLayout>(R.id.native_container)
// ad request parameter
val adParam = AdParam.Builder().setAdUnitId("YOUR_AD_UNIT_ID").build()
// create native ad options
val nativeAdOptions = GfpNativeAdOptions.Builder().setHasMediaView(true).build()
// ad loader
val adLoader = GfpAdLoader.Builder(requireActivity(), adParam)
// set timeout
.withTimeoutMillis(60_000L)
// set listener
.withAdListener(object: AdEventListener() {
override fun onAdClicked() {
// AD Clicked
}
override fun onAdImpression() {
// AD Impression
}
override fun onAdMuted() {
// AD Muted
}
override fun onAdMetaChanged(params: Map<String, String>) {
// AD Meta Changed
}
override fun onError(error: GfpError, responseInfo: GfpResponseInfo) {
Log.e("NativeBannerFragment", responseInfo.toString())
}
})
// set ad option and add listener
.withNativeAd(
nativeAdOptions,
object: GfpNativeAd.OnNativeAdLoadedListener {
override fun onNativeAdLoaded(gfpNativeAd: GfpNativeAd) {
inflateAd(gfpNativeAd)
}
}
)
.build()
adLoader.loadAd()
return view
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_native_banner, container, false);
RelativeLayout nativeContainer = view.findViewById(R.id.native_container);
// ad request paramter
AdParam adParam = new AdParam.Builder().setAdUnitId("YOUR_AD_UNIT_ID").build();
// create native ad options
GfpNativeAdOptions nativeAdOptions = new GfpNativeAdOptions.Builder().setHasMediaView(true).build();
// ad loader
GfpAdLoader adLoader = new GfpAdLoader.Builder(requireActivity(), adParam)
// set timeout
.withTimeoutMillis(60_000L)
// set listener
.withAdListener(new AdEventListener() {
@Override
public void onAdClicked() {
// AD click
}
@Override
public void onAdImpression() {
// AD impression
}
@Override
public void onAdMuted() {
// AD Muted
}
@Override
public void onAdMetaChanged(Map<String, String> params) {
// AD MetaChanged
}
@Override
public void onError(GfpError error, GfpResponseInfo responseInfo) {
Log.e("NativeBannerFragment", responseInfo.toString());
}
)
// set ad option and add listener
.withNativeAd(
nativeAdOptions,
new GfpNativeAd.OnNativeAdLoadedListener() {
@Override
public void onNativeAdLoaded(GfpNativeAd gfpNativeAd) {
inflateAd(gfpNativeAd);
}
}
)
.build();
adLoader.loadAd();
return view;
}
4-1. Ad request timeout settings
A separate timeout for each ad request could be set by adding withTimeoutMillis()
of the GfpAdLoader Builder
settings.
If the setting is not selected, the default value will use the global settings (Default: 60 seconds) through SdkProperties
.
4-2. GfpNativeAdOptions
It is used to change the adChoicesView location for native ads or to request a native banner ad without a MediaView
.
Native ad option values are transmitted through withNativeAd()
when creating GfpAdLoader.
-
setAdChoicesPlacement(int)
Used to change the adChoicesView location for DFP/NDA native ads.
infoInMobi native ads not only render AdChoicesView but also internally process the rendering location within the InMobi SDK. Therefore, it will be rendered regardless of the GfpAdChoicesView location in the native ad layout and the adChoicesPlacement value set in GfpNativeAdOptions.
-
setHasMediaView(boolean)
The default is true. If it is set to false, Native Banner advertisements without a MediaView can be rendered.
If it is set to false, there may be the following restrictions.
infoWhen rendering a Native Banner ad, please check with the NAM manager to see whether the Native Banner ad is set up in the ad provider before proceeding to the next step.
- Currently, native advertisements without a MediaView based on the NAM SDK are provided only in DFP and FAN modules.
- When creating a layout containing
GfpNativeAdView
, mediaView must be removed (refer to the ad_media ID in the above layout).
4-3. Reception of ad loading events - GfpNativeAd.OnNativeAdLoadedListener
Load events can be received when an ad is successfully loaded through GfpAdLoader.Builder.withNativeAd(GfpNativeAdOptions, OnNativeAdLoadedListener)
.
At this point, the GfpNativeAd object containing the loaded advertisement information is transmitted to the GfpNativeAd.OnNativeAdLoadedListener.onNativeAdLoaded()
parameter.
As rendering is required when the loading is complete, GfpNativeAdView
needs to be created in the corresponding listener and inflated in native_container
- Kotlin
- Java
val adLoader = GfpAdLoader.Builder(this, adParam)
...
.withNativeAd(
nativeAdOptions,
object: GfpNativeAd.OnNativeAdLoadedListener {
override fun onNativeAdLoaded(nativeAd: GfpNativeAd) {
// success to load
inflateNativeAd(nativeAd)
}
}
)
.build()
adLoader = new GfpAdLoader.Builder(this, adParam)
...
.withNativeAd(
nativeAdOptions,
new GfpNativeAd.OnNativeAdLoadedListener() {
@Override
public void onNativeAdLoaded(GfpNativeAd nativeAd) {
// success to load
inflateNativeAd(nativeAd);
}
}
)
.build();
4-4. AdEventListener
By setting up GfpAdLoader.Builder.withAdListener(AdEventListener)
, events for a click, impression, error, etc. except loading can be received.
[Step 5] Advertisement loading
Advertisements can be loaded once the settings for GfpAdLoader
have been completed.
When loading ads through a single GfpAdLoader, one request must be made at a time.
When reusing the GfpAdLoader, loadAd()
must be called again after each request is completed to start the next request.
If loadAd()
is called again before the request is complete, the previous load may be canceled or the previously loaded ad may be deleted.
- Kotlin
- Java
import ...
import com.naver.gfpsdk.AdEventListener
import com.naver.gfpsdk.AdParam
import com.naver.gfpsdk.GfpAdChoicesView
import com.naver.gfpsdk.GfpAdLoader
import com.naver.gfpsdk.GfpError
import com.naver.gfpsdk.GfpMediaView
import com.naver.gfpsdk.GfpNativeAd
import com.naver.gfpsdk.GfpNativeAdOptions
import com.naver.gfpsdk.GfpNativeAdView
import com.naver.gfpsdk.GfpResponseInfo
import com.naver.gfpsdk.Image
class NativeBannerFragment : Fragment() {
private lateinit var nativeContainer: RelativeLayout
private lateinit var adLoader: GfpAdLoader
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_native_banner, container, false)
nativeContainer = view.findViewById(R.id.native_container)
val adParam = AdParam.Builder().setAdUnitId(AD_UNIT_ID).build()
val nativeAdOptions = GfpNativeAdOptions.Builder()
.setHasMediaView(true)
.build()
adLoader = GfpAdLoader.Builder(this, adParam)
.withTimeoutMillis(60_000L)
.withAdListener(object: AdEventListener() {
override fun onAdClicked() {
Log.d("NativeBannerFragment", "click")
}
override fun onAdImpression() {
Log.d("NativeBannerFragment", "impression")
}
override fun onError(error: GfpError, responseInfo: GfpResponseInfo) {
val errorString = String.format(
"code[%d] subCode[%s] message[%s] responseInfo[%s]",
error.errorCode,
error.errorSubCode,
error.errorMessage,
responseInfo.toString()
)
Log.e("NativeBannerFragment", errorString)
}
})
.withNativeAd(
nativeAdOptions,
object: GfpNativeAd.OnNativeAdLoadedListener {
override fun onNativeAdLoaded(nativeAd: GfpNativeAd) {
inflateAd(nativeAd)
}
}
)
.build()
adLoader.loadAd()
return view
}
private fun inflateAd(nativeAd: GfpNativeAd) {
// rendering native ad
}
companion object {
private const val AD_UNIT_ID = "YOUR_AD_UNIT_ID"
}
}
import ...
import com.naver.gfpsdk.AdEventListener;
import com.naver.gfpsdk.AdParam;
import com.naver.gfpsdk.GfpAdChoicesView;
import com.naver.gfpsdk.GfpAdLoader;
import com.naver.gfpsdk.GfpError;
import com.naver.gfpsdk.GfpMediaView;
import com.naver.gfpsdk.GfpNativeAd;
import com.naver.gfpsdk.GfpNativeAdOptions;
import com.naver.gfpsdk.GfpNativeAdView;
import com.naver.gfpsdk.GfpResponseInfo;
import com.naver.gfpsdk.Image;
public class NativeBannerFragment extends Fragment {
private static final String AD_UNIT_ID = "YOUR_AD_UNIT_ID";
private RelativeLayout nativeContainer;
private GfpAdLoader adLoader;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_native_banner, container, false);
nativeContainer = view.findViewById(R.id.native_container);
AdParam adParam = new AdParam.Builder().setAdUnitId(AD_UNIT_ID).build();
GfpNativeAdOptions nativeAdOptions = new GfpNativeAdOptions.Builder()
.setHasMediaView(true)
.build();
adLoader = new GfpAdLoader.Builder(this, adParam)
.withTimeoutMillis(60_000L)
.withAdListener(new AdEventListener() {
@Override
public void onAdClicked() {
Log.d("NativeBannerFragment", "click");
}
@Override
public void onAdImpression() {
Log.d("NativeBannerFragment", "impression");
}
public void onError(GfpError error, GfpResponseInfo responseInfo) {
String errorString = String.format("code[%d] subCode[%s] message[%s] responseInfo[%s]",
error.getErrorCode(),
error.getErrorSubCode(),
error.getErrorMessage(),
responseInfo.toString()
);
Log.e("NativeBannerFragment", errorString);
}
})
.withNativeAd(nativeAdOptions, new GfpNativeAd.OnNativeAdLoadedListener() {
@Override
public void onNativeAdLoaded(GfpNativeAd nativeAd) {
inflateAd(nativeAd);
}
})
.build();
adLoader.loadAd();
return view;
}
private void inflateAd(GfpNativeAd nativeAd) {
// rendering native ad
}
}
[Step 6] Rendering advertisements
When an advertisement is successfully loaded, GfpNativeAd
is received. Through this object, the meta information of the assets is retrieved.
Keep the following in mind when rendering:
- Set the
assetsContainer
andadChoicesView
in theGfpNativeAdView
object. - If this is not set, an exception occurs.
- Set the assetView for icon, title, body, callToAction, advertiser, and socialContext in the
GfpNativeAdView
object. - If this is not set, a click event may not occur.
- Call
setNativeAd()
on theGfpNativeAdView
object. - If this is not done, operation problems may occur since the previous advertising object is not cleared when advertising providers add a forced layout and reuse it.
- When the Native Banner ad is set,
setMediaView(mediaView)
must not be called to the (GfpNativeAdOptions.setHasMediaView(false)
)GfpNativeAdView object
. Since the media view is disabled, an exception occurs during the validation process.
- Kotlin
- Java
private fun inflateAd(nativeAd: GfpNativeAd) {
nativeContainer.removeAllViews()
val nativeAdView = layoutInflater.inflate(R.layout.content_native_ad, nativeContainer, false) as GfpNativeAdView
nativeContainer.addView(nativeAdView)
with(nativeAdView) {
val assetsContainer = findViewById<FrameLayout>(R.id.assets_container)
val mediaView = findViewById<GfpMediaView>(R.id.ad_media)
val adChoicesView = findViewById<GfpAdChoicesView>(R.id.ad_choices_view)
val iconView = findViewById<ImageView>(R.id.ad_app_icon)
val titleView = findViewById<TextView>(R.id.ad_headline)
val bodyView = findViewById<TextView>(R.id.ad_body)
val advertiserView = findViewById<TextView>(R.id.ad_advertiser)
val socialContextView = findViewById<TextView>(R.id.ad_social_context)
val callToActionButton = findViewById<Button>(R.id.ad_call_to_action)
val noticeView = findViewById<TextView>(R.id.ad_notice)
setAssetsContainer(assetsContainer)
setAdChoicesView(adChoicesView)
setIconView(iconView)
setTitleView(titleView)
setBodyView(bodyView)
setAdvertiserView(advertiserView)
setSocialContextView(socialContextView)
setCallToActionView(callToActionButton)
setNoticeView(noticeView)
setMediaView(mediaView)
}
nativeAd.run {
titleView.text = title
bodyView.text = body
callToActionButton.text = callToAction
advertiserView.text = advertiserName
icon?.let {
iconView.setImageDrawable(it.drawable)
iconView.visibility = View.VISIBLE
} ?: iconView.visibility = View.GONE
socialContext?.let {
socialContextView.text = it
socialContextView.visibility = View.VISIBLE
} ?: socialContextView.visibility = View.GONE
notice?.let {
noticeView.text = it
noticeView.visibility = View.VISIBLE
} ?: noticeView.visibility = View.GONE
nativeAdView.setNativeAd(this)
}
}
private void inflateAd(GfpNativeAd nativeAd) {
nativeContainer.removeAllViews();
GfpNativeAdView nativeAdView = (GfpNativeAdView) getLayoutInflater()
.inflate(R.layout.content_native_ad, nativeContainer, false);
nativeContainer.addView(nativeAdView);
FrameLayout assetsContainer = nativeAdView.findViewById(R.id.assets_container);
GfpMediaView mediaView = nativeAdView.findViewById(R.id.ad_media); // if you setmedia view - GfpNativeAdOptions.setHasMediaView(true)
GfpAdChoicesView adChoicesView = nativeAdView.findViewById(R.id.ad_choices_view);
ImageView iconView = nativeAdView.findViewById(R.id.ad_app_icon);
TextView titleView = nativeAdView.findViewById(R.id.ad_headline);
TextView bodyView = nativeAdView.findViewById(R.id.ad_body);
TextView advertiserView = nativeAdView.findViewById(R.id.ad_advertiser);
TextView socialContextView = nativeAdView.findViewById(R.id.ad_social_context);
Button callToActionButton = nativeAdView.findViewById(R.id.ad_call_to_action);
TextView noticeView = nativeAdView.findViewById(R.id.ad_notice);
nativeAdView.setAssetsContainer(assetsContainer);
nativeAdView.setAdChoicesView(adChoicesView);
nativeAdView.setIconView(iconView);
nativeAdView.setTitleView(titleView);
nativeAdView.setBodyView(bodyView);
nativeAdView.setAdvertiserView(advertiserView);
nativeAdView.setSocialContextView(socialContextView);
nativeAdView.setCallToActionView(callToActionButton);
nativeAdView.setNoticeView(noticeView);
nativeAdView.setMediaView(mediaView); // if you set media view -GfpNativeAdOptions.setHasMediaView(true)
titleView.setText(nativeAd.getTitle());
bodyView.setText(nativeAd.getBody());
callToActionButton.setText(nativeAd.getCallToAction());
advertiserView.setText(nativeAd.getAdvertiserName());
if (nativeAd.icon != null) {
iconView.setImageDrawable(nativeAd.icon.getDrawable());
iconView.setVisibility(View.VISIBLE);
} else {
iconView.setVisibility(View.GONE);
}
if (nativeAd.getSocialContext() != null) {
socialContextView.setText(nativeAd.getSocialContext());
socialContextView.setVisibility(View.VISIBLE);
} else {
socialContextView.setVisibility(View.GONE);
}
if (nativeAd.getNotice() != null) {
noticeView.setText(nativeAd.getNotice());
noticeView.setVisibility(View.VISIBLE);
} else {
noticeView.setVisibility(View.GONE);
}
nativeAdView.setNativeAd(nativeAd);
}
[Step 7] Advertisement removal
Once the display of the native ad is terminated, the ad must be removed for proper disposal.
To remove an ad, call cancel()
provided by GfpAdLoader
as shown below.
- Kotlin
- Java
override fun onDestroy() {
super.onDestroy()
adLoader?.let { it.cancel() }
}
@Override
public void onDestroy() {
super.onDestroy();
if (adLoader != null) {
adLoader.cancel();
}
}
Appendix. Assets supported by NAM SDK for each DSP
1. Assets supported by NAM SDK for FAN Native ads
Asset | Support | Note |
---|---|---|
title | O | |
image | O | Not used when rendering with Native Banner; Transmit uri, width, height values |
body | O | |
icon | O | Transmit uri, width, height values |
call to action | O | |
advertiser name | O | Items added from FAN SDK version 4.99.0 or higher |
social context | O |
2. Assets supported by NAM SDK for DFP Native ads
Asset | Support | Note |
---|---|---|
title | O | |
image | O | Transmit drawable, uri, scale, width, height values |
body | O | |
icon | O | Transmit drawable, uri, scale, width, height values |
call to action | O | |
advertiser name | O | |
social context | X |
3. Assets supported by NAM SDK for InMobi Native ads
Asset | Support | Note |
---|---|---|
title | O | |
image | O | InMobi does not provide image assets in native ads (videos, images) |
body | O | |
icon | O | Transmit drawable and uri values |
call to action | O | |
advertiser name | X | |
social context | X |
4. Assets supported by NAM SDK for AppLovin Native ads
Asset | Support | Note |
---|---|---|
title | O | Must be included |
image | O | Not used when rendering with Native Banner |
body | O | |
icon | O | |
call to action | O | Must be a Button object |
advertiser name | O | |
social context | X |