This page explains how to integrate the Teads inApp SDK in application using WebView to display content.
If you are not using a WebView, I.e. If the content is display using native components, please follow the Standard integration documentation.
- Webview integration basics
- Prerequisites
- Implementation
- Event Monitoring
- Configuration Changes
- Brand Safety and web content URL
- Check list
- Additional settings
The Teads Standard JavaScript Tag used for classic web integration cannot be used for the inApp context (WebView containers included).
WebViews are powerful components that allows Android applications to display content from the web directly inside an application.
Even though JavaScript can be executed, WebViews are sandboxed containers isolating the Teads Standard JavaScript Tag from contextual data breaking features such as brand safety, viewability measurement, fraud detection, dynamic creatives, etc.
These limitations make the Teads inApp SDK the only way to safely deliver Teads ads in app context.
Webview integration basics
The Teads inApp SDK will open a blank slot inside the article HTML at the location you'll define.
A view component is created over the blank space and will contain the ad.
This view is synchronized with the user scroll creating the illusion of the player inside the article.
As we can't choose the player position in the article, this integration requires a custom setup on your side. We do propose a "helper file" that helps in this step (see prerequisites section)
Please note, as each app is differently shaped, we do encourage you to customize the "helper file" to match your own needs.
Due to its customizable nature, this Helper file is not included in the SDK package, but downloadable separately
Prerequisites
- Import the Teads inApp SDK in your project.
- Ensure the application uses WebViews to display article content.
- Import (and adapt) this Helper module
Important
WebView integrations are too tied to your code architecture, pattern and framework.
Unfortunately, there is no universal way to fit all WebView integrations.The proposed "Helper" is a generic module meant to help you tailor the integration to your basic needs.
Please note you might need to adapt and complete it since it does not cover all situations.
Hence, these files are not included in the SDK package.
Please, keep in mind we might update it from time to time outside the SDK release cycle.
Implementation
The article is using the landscape test PID 84242. This PID is meant for testing purpose and shall not be released into production.
Please retrieve your production PID from your local account manager.
First, The WebView used should be an instance of the ObservableWebView copied in the prerequisite part.
<com.your.app.ObservableWebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Then, create a new InReadAdPlacement
and SyncAdWebView
and load your webview content with a CustomInReadWebviewClient
class InReadWebViewFragment : BaseFragment(), SyncAdWebView.Listener {
private lateinit var webviewHelperSynch: SyncAdWebView
private lateinit var adPlacement: InReadAdPlacement
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_inread_webview, container, false)
}
@SuppressLint("SetJavaScriptEnabled")
override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) {
val placementSettings = AdPlacementSettings.Builder()
.enableDebug()
.build()
adPlacement = TeadsSDK.createInReadPlacement(requireActivity(), pid, placementSettings)
webviewHelperSynch = SyncAdWebView(requireContext(), webview, this@InReadWebViewFragment, "#teads-placement-slot")
webview.settings.javaScriptEnabled = true
webview.webViewClient = CustomInReadWebviewClient(webviewHelperSynch, getTitle())
webview.loadUrl("https://example.com/article_1")
}
}
Implement SyncWebViewTeadsAdView.Listener
to load the ad after the WebView is ready to receive one
override fun onHelperReady(adContainer: ViewGroup) {
val requestSettings = AdRequestSettings.Builder()
.pageSlotUrl("https://example.com/article_1")
.build()
adPlacement.requestAd(requestSettings, object : InReadAdListener {
override fun adOpportunityTrackerView(trackerView: AdOpportunityTrackerView) {
// register the AdOpportunityTrackerView inside the webview ad container
webviewHelperSynch.registerTrackerView(trackerView)
}
override fun onAdReceived(inReadAdView: InReadAdView, adRatio: AdRatio) {
// register the InReadAdView inside the webview ad container and will open the slot with specified ratio
webviewHelperSynch.registerAdView(inReadAdView)
webviewHelperSynch.updateSlot(adRatio.getAdSlotRatio(webview.measuredWidth))
}
override fun onAdRatioUpdate(adRatio: AdRatio) {
// Will update the ratio with the new ratio received from ad experience
webviewHelperSynch.updateSlot(adRatio.getAdSlotRatio(webview.measuredWidth))
}
override fun onAdClosed() {
webviewHelperSynch.closeAd()
}
override fun onAdError(code: Int, description: String) {
webviewHelperSynch.clean()
}
override fun onFailToReceiveAd(failReason: String) {
webviewHelperSynch.clean()
}
override fun onAdClicked() {}
override fun onAdImpression() {}
})
}
Event Monitoring
The Teads inApp SDK provides a set of listeners to let you monitor a large scope of events all along ad life cycle. This helps tailor the ad experience in your app, e.g., closing the ad view in case of onAdError
, resize the ad view in case of onAdRatioUpdate
.
interface InReadAdListener {
// When an impression has occurred
fun onAdImpression()
// When an event click has been fired
fun onAdClicked()
// When the ad experience has experienced an issue
fun onAdError(code: Int, description: String)
// When the ad has been closed
fun onAdClosed()
// This is the entry point of an Ad correctly loaded by Teads
fun onAdReceived(inReadAdView: InReadAdView, adRatio: AdRatio)
// When Teads inApp SDK has failed to retrieve an ad
fun onFailToReceiveAd(failReason: String)
// This is the monitoring slot tracker view (see Slot Monitoring section below)
fun adOpportunityTrackerView(trackerView: AdOpportunityTrackerView)
// When an ad has updated its ratio, you need to update your container view
fun onAdRatioUpdate(adRatio: AdRatio)
}
Configuration Changes
Some applications handle the configuration change themselves instead of letting the Android system restarting their activity. This is particularly the case for screen rotation and screen size configuration.
If you have declared in your manifest that you handle the configuration change by adding the android:configChanges
attribute, then you must notify the event to the Webview Helper. It will be responsible to calculate the new size and the new coordinates of the ad slot.
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
webviewHelperSynch.onConfigurationChanged()
}
Brand Safety and web content URL
Having brand safe content will optimize fill rate since advertisers are less keen to have their brand associated with "bad" context (violence/adult etc.).
⚠️ Teads guarantees brand safe contents to advertiser by analysing the overall content of the loaded page. This is an important requirement for advertiser. The Fill Rate of your app could be impacted if BrandSafety analysis is not enabled.
The categorization is done on the fly by a 3rd party partner, Grapeshot.
Brand safe analyze is limited to web content only.
This technical limitation is bypassed inApp using pageSlotUrl
to provide the Web equivalent URL of the current article Grapeshot will perform analysis in.
If your application doesn't have a website equivalent, the pageSlotUrl
method can be ignored.
AdSettings.Builder()
.pageSlotUrl("https://example.com/my_article_1")
.build()
Check list
- ✅ Ensure Brand Safety is enabled
- ✅ Ensure you comply with privacy legal requirements (GDPR/CCPA/GPP)
- ✅ Comply with app-ads.txt
- ✅ Enable ad view resizing
- ✅ Enable slot monitoring for ad opportunities
- ✅ Clean the ad view when necessary
- ✅ Test different PIDs with various ad formats and sizes
- ✅ Enable validation mode to ensure key features are working
Additional settings
Find the full available AdPlacementSettings
and AdRequestSettings
settings here:
Example:
AdPlacementSettings.Builder()
// Enable debug logs
.enableDebug()
// GDPR
.userConsent([SUBJECT_TO_GDPR], [CONSENT_STRING], TCFVersion.V2, cmpSdkId)
.build()