Advanced Usage
This guide covers advanced usage scenarios and features of the Nexad Android SDK for developers who want to implement more sophisticated ad integrations.
Custom Implementations for Chat Message Ads
While the SDK provides a high-level API for chat message ads, you can also build a custom implementation:
// 1. Load native ad with the chat_message placement
NexadSDK.getInstance().loadNativeAd("chat_message", object : AdDataLoadCallback {
override fun onSuccess(ads: List<Ad>) {
for (ad in ads) {
// 2. Create ad view with chat message placement
val adView = NexadSDK.getInstance().createNativeAdView(
context,
NativeAdViewFactory.PLACEMENT_CHAT_MESSAGE,
style = customStyle // Optional custom style
)
// 3. Configure the view with ad data
adView.configure(ad)
// 4. Add to your chat container
chatContainer.addView(adView)
}
}
override fun onFailure(error: Exception) {
Log.e("ChatAds", "Failed to load chat message ad: ${error.message}")
}
})
Managing User Data
The SDK allows you to provide user data to improve ad targeting:
// Create a user profile
val userProfile = UserProfile(
nickname = "user123",
age = 28,
gender = Gender.MALE,
interests = listOf("technology", "sports", "travel"),
location = Location(
country = "US",
region = "CA",
city = "San Francisco"
),
customAttributes = mapOf(
"subscription_tier" to "premium",
"user_type" to "returning"
)
)
// Set the user profile
val user = NexadUser(
userId = "unique-user-id",
deviceId = deviceId,
userProfile = userProfile,
publisherUserId = "publisher-specific-id",
email = "[email protected]",
language = "en-US"
)
NexadSDK.getInstance().setUser(user)
Handling Conversation Context
For chat applications, providing rich conversation context can improve ad relevance:
// Create a detailed conversation context
val conversationContext = ConversationContext(
sessionId = UUID.randomUUID().toString(),
query = "What smartphones have the best cameras?",
scene = SceneType.CHAT_CONVERSATION,
messages = listOf(
Message(
id = "msg1",
sender = MessageSender.USER,
content = "I need a new smartphone",
type = MessageType.TEXT,
timestamp = System.currentTimeMillis() - 60000
),
Message(
id = "msg2",
sender = MessageSender.BOT,
content = "What features are most important to you?",
type = MessageType.TEXT,
timestamp = System.currentTimeMillis() - 45000
),
Message(
id = "msg3",
sender = MessageSender.USER,
content = "Camera quality is my top priority",
type = MessageType.TEXT,
timestamp = System.currentTimeMillis() - 30000
),
Message(
id = "msg4",
sender = MessageSender.BOT,
content = "Great, there are several options with excellent cameras. What's your budget?",
type = MessageType.TEXT,
timestamp = System.currentTimeMillis() - 15000
),
Message(
id = "msg5",
sender = MessageSender.USER,
content = "What smartphones have the best cameras?",
type = MessageType.TEXT,
timestamp = System.currentTimeMillis()
)
),
chatbotContext = ChatbotContext(
botName = "TechAdvisor",
botDescription = "A knowledgeable assistant for technology recommendations",
sessionId = "session-123",
topic = "smartphone_recommendations",
conversations = listOf(
Conversation(
timestamp = System.currentTimeMillis() - 60000,
role = "user",
content = "I need a new smartphone"
),
Conversation(
timestamp = System.currentTimeMillis() - 45000,
role = "assistant",
content = "What features are most important to you?"
),
Conversation(
timestamp = System.currentTimeMillis() - 30000,
role = "user",
content = "Camera quality is my top priority"
),
Conversation(
timestamp = System.currentTimeMillis() - 15000,
role = "assistant",
content = "Great, there are several options with excellent cameras. What's your budget?"
),
Conversation(
timestamp = System.currentTimeMillis(),
role = "user",
content = "What smartphones have the best cameras?"
)
)
),
customContext = mapOf(
"search_history" to listOf("camera comparison", "best smartphone 2023"),
"device_preferences" to listOf("Android", "high-end")
)
)
// Use in ad loading
NexadSDK.getInstance().loadAd(
placement = "chat_result",
context = conversationContext,
callback = adLoadCallback
)
Implementing Linkify Ads
Linkify ads can highlight specific keywords in text and make them interactive:
// Create linkify settings
val linkifySetting = LinkifySetting(
queryId = "query-123",
k = 3, // Number of ad candidates to reserve for linkify matching
linkifyOnly = false // Whether to only deliver linkify ad candidates
)
// Create context with linkify settings
val context = ConversationContext(
sessionId = "session-123",
query = "smartphone recommendations",
messages = messagesList,
linkifySetting = linkifySetting
)
// Load ads with linkify context
NexadSDK.getInstance().loadAd(
placement = "text_content",
context = context,
callback = object : AdLoadCallback {
override fun onSuccess(ad: Ad) {
// Process the ad with linkify data
processLinkifyAd(ad)
}
override fun onFailure(error: Exception) {
Log.e("NexadSDK", "Failed to load linkify ad", error)
}
}
)
// Process linkify ad
private fun processLinkifyAd(ad: Ad) {
// Get linkify data from extra attributes
val linkifyData = ad.extraAttributes?.get("linkify_data") as? Map<String, Any>
linkifyData?.let {
val keywords = it["keywords"] as? List<String>
val displayText = it["display_text"] as? String
// Apply to your text content
applyLinkifyToText(textView, keywords, displayText, ad)
}
}
// Apply linkify to text
private fun applyLinkifyToText(textView: TextView, keywords: List<String>?, displayText: String?, ad: Ad) {
val originalText = textView.text.toString()
val spannableString = SpannableString(originalText)
keywords?.forEach { keyword ->
val pattern = Pattern.compile("\\b" + Pattern.quote(keyword) + "\\b", Pattern.CASE_INSENSITIVE)
val matcher = pattern.matcher(originalText)
while (matcher.find()) {
val start = matcher.start()
val end = matcher.end()
// Create clickable span
val clickableSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
// Handle ad click
ad.clickThroughUrl?.let { url ->
openUrl(context, url)
}
// Track click
ad.trackingUrls?.clickTrackingUrls?.forEach { trackUrl ->
NexadSDK.getInstance().trackUrl(trackUrl)
}
}
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.isUnderlineText = true
ds.color = Color.BLUE
}
}
spannableString.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
textView.text = spannableString
textView.movementMethod = LinkMovementMethod.getInstance()
}
A/B Testing Support
The SDK supports A/B testing to optimize ad performance:
// Check experiment variant
val ad: Ad = // ... loaded ad
val variant = ad.experimentVariant
// Log analytics based on variant
if (variant == "control") {
// Control group behavior
analyticsTracker.logEvent("ad_shown_control", mapOf("ad_id" to ad.id))
} else if (variant == "test_variant_a") {
// Test variant A behavior
analyticsTracker.logEvent("ad_shown_variant_a", mapOf("ad_id" to ad.id))
}
Error Handling and Monitoring
Implement robust error handling for better reliability:
NexadSDK.getInstance().loadAd(
placement = "placement_id",
context = adContext,
callback = object : AdLoadCallback {
override fun onSuccess(ad: Ad) {
// Success handling
}
override fun onFailure(error: Exception) {
when (error) {
is NetworkError -> {
// Handle network-related errors
Log.e("NexadSDK", "Network issue: ${error.message}")
// Retry with exponential backoff
if (retryCount < MAX_RETRIES) {
handler.postDelayed({
retryLoadAd(placement, context, ++retryCount)
}, calculateBackoffDelay(retryCount))
} else {
showFallbackContent()
}
}
is InvalidConfiguration -> {
// Handle configuration errors
Log.e("NexadSDK", "Configuration issue: ${error.message}")
fireErrorAnalytics("config_error", error.message)
}
is AdLoadError -> {
// Handle ad loading errors
Log.e("NexadSDK", "Ad load error: ${error.message}")
showFallbackContent()
}
else -> {
// Handle other errors
Log.e("NexadSDK", "Unknown error: ${error.message}")
fireErrorAnalytics("unknown_error", error.message)
}
}
}
}
)
// Calculate backoff delay
private fun calculateBackoffDelay(retryCount: Int): Long {
return min(
1000L * 2.0.pow(retryCount.toDouble()).toLong(),
MAX_BACKOFF_DELAY
)
}
Performance Optimization
Optimize ad loading to improve performance:
// Preload ads for common placements
fun preloadCommonAds() {
// Preload for chat screen
NexadSDK.getInstance().preloadAd(
placement = "chat_message",
context = defaultChatContext,
count = 3
)
// Preload for search results
NexadSDK.getInstance().preloadAd(
placement = "search_results",
context = defaultSearchContext,
count = 5
)
}
// Use preloaded ads
NexadSDK.getInstance().getPreloadedAd(
placement = "chat_message",
callback = object : AdLoadCallback {
override fun onSuccess(ad: Ad) {
// Use preloaded ad
displayAd(ad)
}
override fun onFailure(error: Exception) {
// Fall back to regular loading
NexadSDK.getInstance().loadAd(
placement = "chat_message",
context = currentContext,
callback = this
)
}
}
)
Memory Management
Proper memory management is crucial for maintaining app performance:
// Register ad view for lifecycle management
NexadSDK.getInstance().registerView(adView, ad)
// In your activity or fragment
override fun onDestroy() {
super.onDestroy()
// Unregister ad views to prevent memory leaks
adViews.forEach { adView ->
NexadSDK.getInstance().unregisterView(adView)
}
// Clear any cached data if needed
if (isFinishing) {
NexadSDK.getInstance().clearCache()
}
}
These advanced techniques will help you make the most of the Nexad Android SDK and provide an optimal advertising experience in your application.