Back to Bidding-Only Integration
Visit the AdOps guide for instructions on setting up the In-App creatives on GAM.
At a high level, the in-app workflow is happening the following way:
Integration Example
private fun createAd() {
// 1. Create NativeAdUnit
adUnit = NativeAdUnit(CONFIG_ID);
adUnit?.setContextType(NativeAdUnit.CONTEXT_TYPE.SOCIAL_CENTRIC)
adUnit?.setPlacementType(NativeAdUnit.PLACEMENTTYPE.CONTENT_FEED)
adUnit?.setContextSubType(NativeAdUnit.CONTEXTSUBTYPE.GENERAL_SOCIAL)
// 2. Add native assets and trackers
addNativeAssets(adUnit)
// 3. Make a bid request to Prebid Server
val adRequest = AdManagerAdRequest.Builder().build()
adUnit?.fetchDemand(adRequest) {
// 4. Load a GAM Native Ad
adLoader = createAdLoader(adWrapperView)
adLoader?.loadAd(adRequest)
}
}
Add native assets:
private fun addNativeAssets(adUnit: NativeAdUnit?) {
// ADD NATIVE ASSETS
val title = NativeTitleAsset()
title.setLength(90)
title.isRequired = true
adUnit?.addAsset(title)
val icon = NativeImageAsset(20, 20, 20, 20)
icon.imageType = NativeImageAsset.IMAGE_TYPE.ICON
icon.isRequired = true
adUnit?.addAsset(icon)
val image = NativeImageAsset(200, 200, 200, 200)
image.imageType = NativeImageAsset.IMAGE_TYPE.MAIN
image.isRequired = true
adUnit?.addAsset(image)
val data = NativeDataAsset()
data.len = 90
data.dataType = NativeDataAsset.DATA_TYPE.SPONSORED
data.isRequired = true
adUnit?.addAsset(data)
val body = NativeDataAsset()
body.isRequired = true
body.dataType = NativeDataAsset.DATA_TYPE.DESC
adUnit?.addAsset(body)
val cta = NativeDataAsset()
cta.isRequired = true
cta.dataType = NativeDataAsset.DATA_TYPE.CTATEXT
adUnit?.addAsset(cta)
// ADD NATIVE EVENT TRACKERS
val methods = ArrayList<EVENT_TRACKING_METHOD>()
methods.add(EVENT_TRACKING_METHOD.IMAGE)
methods.add(EVENT_TRACKING_METHOD.JS)
try {
val tracker = NativeEventTracker(NativeEventTracker.EVENT_TYPE.IMPRESSION, methods)
adUnit?.addEventTracker(tracker)
} catch (e: Exception) {
e.printStackTrace()
}
}
Prepare Native Ad Loader
private fun createAdLoader(wrapper: ViewGroup): AdLoader? {
val onGamAdLoaded = OnAdManagerAdViewLoadedListener { adManagerAdView: AdManagerAdView ->
Log.d(TAG, "Gam loaded")
adView = adManagerAdView
wrapper.addView(adManagerAdView)
}
val onUnifiedAdLoaded = OnNativeAdLoadedListener { unifiedNativeAd: NativeAd? ->
Log.d(TAG, "Unified native loaded")
this.unifiedNativeAd = unifiedNativeAd
}
val onCustomAdLoaded = OnCustomFormatAdLoadedListener { nativeCustomTemplateAd: NativeCustomFormatAd? ->
Log.d(TAG, "Custom ad loaded")
// 5. Find Prebid Native Ad
AdViewUtils.findNative(nativeCustomTemplateAd!!, object : PrebidNativeAdListener {
override fun onPrebidNativeLoaded(ad: PrebidNativeAd) {
// 6. Render native ad
inflatePrebidNativeAd(ad, wrapper)
}
override fun onPrebidNativeNotFound() {
Log.e(TAG, "onPrebidNativeNotFound")
}
override fun onPrebidNativeNotValid() {
Log.e(TAG, "onPrebidNativeNotValid")
}
})
}
return AdLoader.Builder(wrapper.context, AD_UNIT_ID)
.forAdManagerAdView(onGamAdLoaded, AdSize.BANNER)
.forNativeAd(onUnifiedAdLoaded)
.forCustomFormatAd(
CUSTOM_FORMAT_ID, onCustomAdLoaded
) { customAd: NativeCustomFormatAd?, s: String? -> }
.withAdListener(object : AdListener() {
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
super.onAdFailedToLoad(loadAdError)
Log.e(TAG, "DFP onAdFailedToLoad")
}
})
.build()
}
Render a native ad:
private fun inflatePrebidNativeAd(ad: PrebidNativeAd, wrapper: ViewGroup) {
val nativeContainer = View.inflate(wrapper.context, R.layout.layout_native, null)
val icon = nativeContainer.findViewById<ImageView>(R.id.imgIcon)
ImageUtils.download(ad.iconUrl, icon)
val title = nativeContainer.findViewById<TextView>(R.id.tvTitle)
title.text = ad.title
val image = nativeContainer.findViewById<ImageView>(R.id.imgImage)
ImageUtils.download(ad.imageUrl, image)
val description = nativeContainer.findViewById<TextView>(R.id.tvDesc)
description.text = ad.description
val cta = nativeContainer.findViewById<Button>(R.id.btnCta)
cta.text = ad.callToAction
ad.registerView(nativeContainer, Lists.newArrayList(icon, title, image, description, cta), SafeNativeListener())
wrapper.addView(nativeContainer)
}
The listener that you put in registerView() method must not contain any references to View or Activity to prevent memory leak because this listener can remain in the memory for a long time. It’s okay to put null listener if you don’t need it. It’s better to use class implementation with WeakReferences instead of anonymous objects. In Java inner class implementation must be static.
private class SafeNativeListener : PrebidNativeAdEventListener {
override fun onAdClicked() {}
override fun onAdImpression() {}
override fun onAdExpired() {}
}
Initialize the NativeAdUnit
with the following properties:
configId
- an ID of the Stored Impression on the Prebid ServerIn order to make a bid request for the native ads you should provide a description of native assets that should be present in the native bid response. Prebid SDK supports the following set of assets to request.
NativeImageAsset
NativeDataAsset
NativeTitleAsset
Type | Scope | Description |
---|---|---|
Main | Optional | The image that will be displayed in the native ad. Include a value for minimumWidth and minimumHeight . Ensure that the NativeAssetImage.type is set to ImageAsset.Main |
Icon | Optional | The icon that will be displayed with the native ad. Include a value for minimumWidth and minimumHeight . Ensure that the NativeAssetImage.type is set to ImageAsset.Icon. |
Type | Scope | Description |
---|---|---|
Description | Optional | The content to appear with the ad. Ensure that the type is set to DataAsset.description . |
ctatext | Optional | The text for the call to action button of the native ad. Ensure that the type is set to DataAsset.ctatext . |
Sponsored | Optional | The sponsor (brand) of the native ad. Ensure that the type is set to DataAsset.sponsored . |
Type | Scope | Description |
---|---|---|
Title | Optional | The title of the native ad. |
Using the NativeParameters
object (with the PrebidRequest object) or the NativeRequest
object, you can customize the bid request for native ads.
The array of requested asset objects. Prebid SDK supports all kinds of assets according to the IAB spec except video
.
The array of requested native trackers. Prebid SDK supports inly image
trackers according to the IAB spec.
Version of the Native Markup version in use. The default value is 1.2
The context in which the ad appears.
A more detailed context in which the ad appears.
The design/format/layout of the ad unit being offered.
The number of identical placements in this Layout.
0 for the first ad, 1 for the second ad, and so on.
Whether the supply source/impression supports returning an assetsurl instead of an asset object. 0 or the absence of the field indicates no such support.
Whether the supply source / impression supports returning a dco url instead of an asset object. 0 or the absence of the field indicates no such support.
Set to 1 when the native ad supports buyer-specific privacy notice. Set to 0 (or field absent) when the native ad doesn’t support custom privacy links or if support is unknown.
This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
The fetchDemand
method makes a bid request to the Prebid Server. You should provide an AdManagerAdRequest
object to this method so Prebid SDK sets the targeting keywords of the winning bid for future ad requests.
Prepare the AdManagerAdRequest
and run an ad request as described in the GMA SDK docs for the native ads.
If the AdManagerAdRequest
contains targeting keywords, the respective Prebid line item will be returned from GAM, and GMA SDK will render its creative. Be sure that you make the ad request with the same AdManagerAdRequest
object that you passed to the fetchDemand
method. Otherwise, the ad request won’t contain targeting keywords, and Prebid’s ad won’t ever be displayed.
In order to capture the native ad response, you will need to implement OnCustomFormatAdLoadedListener protocol.
You should use the following Prebid function to determine whether the Prebid line item should be rendered:
AdViewUtils.findNative(...)
Without it, the SDK won’t be able to recognize the Prebid line item.
Once the Prebid line item is recognized you should extract the ad from the winning bid and init the view properties with native assets data.