Migration Guide for Existing Teads SDK Users
Welcome to the Teads Unified SDK! If you're currently using Teads SDK v5.x.x, this guide will help you understand what's new and how to take advantage of the enhanced features while maintaining full backward compatibility.
Key Points
✅ No Breaking Changes - Your existing code continues to work without modifications
✅ New Placements Available - Access to Feed and Recommendations placements
✅ Enhanced Event System - More granular event tracking and monitoring
✅ Complete Backward Compatibility - All existing APIs remain fully functional
Compatibility Matrix
| Feature | Teads SDK v5.x.x | Unified SDK v6.0.0 | Notes |
|---|---|---|---|
| Media Placement | ✅ | ✅ | Fully backward compatible |
| inFeed Native Placement | ✅ | ✅ | Fully backward compatible |
| User Consent Signals Management | ✅ | ✅ | Fully backward compatible |
| Media | ❌ | ✅ | New placement type that encapsulates inRead |
| Media Native | ❌ | ✅ | New placement type that encapsulates inFeed Native |
| Feed | ❌ | ✅ | New placement |
| Recommendations | ❌ | ✅ | New placement |
| Unified Ad Lifecycle Events | ❌ | ✅ | New optional interface |
What's New for You
1. Current Placements Updates
While your existing code still works, you now have access to new interfaces:
| Legacy Placement | New Unified Placement | Description | What is New |
|---|---|---|---|
| Media | Media Placement | Premium video advertising that integrates with content | Ad resizing can now be handled under the hood. New ad lifecycle event interface. More straightforward way to request and load ads. |
| InFeed Native | Media Native Placement | Native video advertising with custom layouts | New Ad Lifecycle event interface. More straightforward way to request and load ads. |
Previous Approach (Still Works)
// Traditional Teads SDK approach - still fully supported
val inReadPlacement = TeadsSDK.createMediaPlacement(
applicationContext,
84242,
placementSettings
)
inReadPlacement.requestAd(
adRequestSettings,
inReadListenerCallback,
videoPlaybackListenerCallback
)
New Approach (Recommended)
// New unified interface - cleaner and more intuitive
val config = TeadsAdPlacementMediaConfig(
pid = 84242,
articleUrl = "https://yoursite.com/article".toUri()
)
val mediaPlacement = TeadsAdPlacementMedia(config, delegate = teadsAdPlacementEventsDelegateCallback)
val adView = mediaPlacement.loadAd()
Media Placement Sample
Media placements display premium video advertisements within your content.
import tv.teads.sdk.combinedsdk.adplacement.TeadsAdPlacementMedia
import tv.teads.sdk.combinedsdk.adplacement.config.TeadsAdPlacementMediaConfig
import tv.teads.sdk.combinedsdk.adplacement.interfaces.TeadsAdPlacementEventsDelegate
import tv.teads.sdk.combinedsdk.TeadsAdPlacementEventName
import android.net.Uri
class ContentActivity : AppCompatActivity(), TeadsAdPlacementEventsDelegate {
private var mediaPlacement: TeadsAdPlacementMedia? = null
private lateinit var binding: ActivityArticleBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityArticleBinding.inflate(layoutInflater)
setContentView(binding.root)
setupMediaPlacement()
}
private fun setupMediaPlacement() {
// Create configuration
val config = TeadsAdPlacementMediaConfig(
pid = 84242, // Your unique Placement ID
articleUrl = Uri.parse("https://yoursite.com/article")
)
// Create placement with delegate
mediaPlacement = TeadsAdPlacementMedia(
this, // Context
config, // Placement config
this // Event delegate
)
// Load the ad
val mediaAdView = mediaPlacement?.loadAd()
// Add to your view hierarchy
binding.myContainerAdView.addView(mediaAdView)
}
override fun onPlacementEvent(
placement: TeadsAdPlacement<*, *>,
event: TeadsAdPlacementEventName,
data: Map<String, Any>?
) {
// Listen the ad lifecycle events
}
override fun onDestroy() {
super.onDestroy()
teadsAdPlacementMedia?.clean()
}
}
Important: When using Media Placement, it's mandatory to set your ad container to dynamic sizing instead of fixed dimensions.
This is because ad creatives served for Media Placement have not a fixed size. The VPAID standard allows them to have dynamic dimensions and aspect ratios, meaning they can change size and shape on the fly.
By using dynamic sizing, you ensure the ad container can automatically resize to perfectly fit the creative's content, preventing issues like cropping or blank spaces. This dynamic resizing is crucial for delivering a great user experience and accurately measuring ad performance throughout the entire ad lifecycle, not just at initialization.
XML Implementation: Use android:layout_height="wrap_content" for your ad container.
Compose Implementation: Use Modifier.wrapContentHeight() or Modifier.height(IntrinsicSize.Min) for your ad container.
Media Native Placement Sample
Media Native placements allow you to create custom layouts for video ads that match your app's design.
import tv.teads.sdk.combinedsdk.adplacement.TeadsAdPlacementMediaNative
import tv.teads.sdk.combinedsdk.adplacement.config.TeadsAdPlacementMediaNativeConfig
import tv.teads.sdk.combinedsdk.adplacement.interfaces.TeadsAdPlacementEventsDelegate
import tv.teads.sdk.combinedsdk.TeadsAdPlacementEventName
import tv.teads.sdk.renderer.NativeAdView
import android.net.Uri
class ContentActivity : AppCompatActivity(), TeadsAdPlacementEventsDelegate {
private var nativePlacement: TeadsAdPlacementMediaNative? = null
private var nativeAdView: NativeAdView? = null
private lateinit var binding: ActivityNativeAdBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityNativeAdBinding.inflate(layoutInflater)
setContentView(binding.root)
setupNativeAd()
}
private fun setupNativeAd() {
// Create custom native ad view
nativeAdView = createCustomNativeAdView()
// Create configuration
val config = TeadsAdPlacementMediaNativeConfig(
124859, // Your unique Placement ID
Uri.parse("https://yoursite.com/article")
)
// Create placement
nativePlacement = TeadsAdPlacementMediaNative(
this, // Context
config, // Placement config
this // Event delegate
)
// Load and bind the ad
nativePlacement
?.loadAd()
?.let { binder ->
// Bind the ad native object to your native ad view
binder(binding.myContainerAdView.nativeAdView)
}
}
override fun onPlacementEvent(
placement: TeadsAdPlacement,
event: TeadsAdPlacementEventName,
data: Map<String, Any>?
) {
// Listen the ad lifecycle events
}
override fun onDestroy() {
super.onDestroy()
nativePlacement?.clean()
}
}
2. Unified Ad Lifecycle Event System
The new unified event system provides consistent event handling across all placement types:
class MyActivity : AppCompatActivity(), TeadsAdPlacementEventsDelegate {
override fun onPlacementEvent(
placement: TeadsAdPlacement<*, *>,
event: TeadsAdPlacementEventName,
data: Map<String, Any>?
) {
// Listen the ad lifecycle
Log.d("TeadsSDK", "Event: $event from $placement with data $data")
}
}
Check the full Comprehensive Event Handling sample.
New Placements
1. Feed
Feed placements display content recommendation widgets, perfect for keeping users engaged with related content.
import tv.teads.sdk.combinedsdk.adplacement.TeadsAdPlacementFeed
import tv.teads.sdk.combinedsdk.adplacement.config.TeadsAdPlacementFeedConfig
import tv.teads.sdk.combinedsdk.adplacement.interfaces.TeadsAdPlacementEventsDelegate
import tv.teads.sdk.combinedsdk.TeadsAdPlacementEventName
import android.net.Uri
class ContentActivity : AppCompatActivity(), TeadsAdPlacementEventsDelegate {
private var feedPlacement: TeadsAdPlacementFeed? = null
private lateinit var binding: ActivityContentBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityContentBinding.inflate(layoutInflater)
setContentView(binding.root)
setupFeedPlacement()
}
private fun setupFeedPlacement() {
// Create configuration
val config = TeadsAdPlacementFeedConfig(
articleUrl = Uri.parse("https://yoursite.com/article"),
widgetId = "MB_1", // Your unique Placement ID
installationKey = "YOUR_INSTALLATION_KEY",
widgetIndex = 0,
userId = null, // Optional user ID for personalization
darkMode = false,
testDisplay = false,
extId = null, // External ID
extSecondaryId = null, // External Secondary ID
obPubImpl = null // OB Publisher Implementation
)
// Create placement
feedPlacement = TeadsAdPlacementFeed(
this, // Context
config, // Placement config
this // Event delegate
)
// Load the feed
val feedView = feedPlacement?.loadAd()
// Add to your view hierarchy
binding.myContainerAdView.addView(feedView)
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
feedPlacement?.onActivityConfigurationChanged()
}
override fun onPlacementEvent(
placement: TeadsAdPlacement<*, *>,
event: TeadsAdPlacementEventName,
data: Map<String, Any>?
) {
// Listen the ad lifecycle events
if (placement is TeadsAdPlacementFeed && event == TeadsAdPlacementEventName.CLICKED_ORGANIC) {
val url = data?.get("url") as? String
url?.let {
// Programmatically open browser with the url
}
}
}
}
2. Recommendations
For programmatic access to content recommendations with custom UI:
import tv.teads.sdk.combinedsdk.adplacement.TeadsAdPlacementRecommendations
import tv.teads.sdk.combinedsdk.adplacement.config.TeadsAdPlacementRecommendationsConfig
import tv.teads.sdk.combinedsdk.adplacement.interfaces.TeadsAdPlacementEventsDelegate
import tv.teads.sdk.combinedsdk.TeadsAdPlacementEventName
import com.outbrain.OBSDK.Entities.OBRecommendation
import com.outbrain.OBSDK.Entities.OBRecommendationsResponse
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
class ContentActivity : AppCompatActivity(), TeadsAdPlacementEventsDelegate {
private var recommendationsPlacement: TeadsAdPlacementRecommendations? = null
private lateinit var binding: ActivityRecommendationsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityRecommendationsBinding.inflate(layoutInflater)
setContentView(binding.root)
loadRecommendations()
}
private fun loadRecommendations() {
// Create configuration
val config = TeadsAdPlacementRecommendationsConfig(
Uri.parse("https://yoursite.com/article"),
"SDK_1" // Your unique Placement ID
)
// Create placement
recommendationsPlacement = TeadsAdPlacementRecommendations(
config, // Placement config
this // Event delegate
)
// Fetch recommendations
lifecycleScope.launch {
try {
val recommendations = recommendationsPlacement?.loadAdSuspend()
recommendations?.let { displayRecommendations(it) }
} catch (e: Exception) {
Log.e("TeadsSDK", "Failed to load recommendations: ${e.message}")
}
}
}
private fun displayRecommendations(recommendations: OBRecommendationsResponse) {
binding.recommendationsContainer.removeAllViews()
if (recommendations.all.isNotEmpty()) {
recommendations.all.forEach { recommendations ->
val recommendationView = createRecommendationView(recommendations)
binding.recommendationsContainer.addView(recommendationView)
}
}
}
private fun createRecommendationView(recommendation: OBRecommendation): View {
val binding = RecommendationItemBinding.inflate(LayoutInflater.from(this))
binding.recommendationTitle.text = recommendation.content
binding.recommendationSource.text = recommendation.sourceName
// Load image (using your preferred image loading library)
recommendation.thumbnail?.url?.let { imageUrl ->
// E.g. Glide.with(this).load(imageUrl).into(binding.recommendationImage)
}
// Handle click
binding.root.setOnClickListener {
TeadsAdPlacementRecommendations.getUrl(recommendation)?.let { url ->
// Open URL in browser
}
}
return binding.root
}
override fun onPlacementEvent(
placement: TeadsAdPlacement<*, *>,
event: TeadsAdPlacementEventName,
data: Map<String, Any>?
) {
// Listen the ad lifecycle events
}
}
Common Questions
Q: Do I need to update my existing code?
A: No. Your existing code continues to work without any changes. Migration is optional.
Q: Can I use both old and new APIs in the same app?
A: Yes. Both APIs can coexist in the same application without issues.
Q: Will the old APIs be deprecated?
A: No immediate plans. The traditional APIs remain fully supported.
Q: Is there a performance benefit to migrating?
A: Minor improvements. The new APIs have some optimizations but the difference is minimal.
Q: Can I access Feed and Recommendations placements with the old API?
A: No. It is required the new unified API.
Q: How do I handle privacy settings?
A: Check the guide Privacy & Compliance.
Migration Checklist
- Update to Teads SDK v6.x.x. For detailed installation instructions, see Installation.
- Test existing implementations to confirm they still work
- Identify opportunities to add Feed and Recommendations placements
- Plan gradual migration for existing placements
- Implement new unified event handling
- Add advanced privacy management (optional)
- Test thoroughly in development environment
- Monitor performance and events in production
Support
If you encounter any issues during migration:
- Check the Integration Guide for detailed examples
- Contact Support for assistance
Remember: Migration is optional. Your existing code continues to work, and you can adopt new features at your own pace.
Happy coding with the enhanced Teads Unified SDK!