Android Rewarded Video Ad Integration
Overview
Rewarded video ads are full-screen video ads where users can earn a reward after watching the complete video, with the following characteristics:
- High user engagement
- High revenue potential
- Good user experience
- Suitable for games and utility apps
Integration Steps
Refer to the RewardAdHelper in the demo.
1. Initialize the Rewarded Video Ad
Load a rewarded video ad in an Activity or Fragment:
class RewardAdHelper(private val activity: Activity, private val logger: PrintLogger) {
private var rewardAd: UjuAdObject? = null
/**
* Load a rewarded ad
*
* This method creates an ad config, obtains the rewarded ad object via the factory method,
* sets the ad listener, and finally calls load() to start loading the ad
*/
fun load() {
// Create the ad config object, set the placement ID
// scenarioKey is an optional parameter for tracking ad display scenarios
val adConfig = UjuAdConfig(
placementId = DemoConfig.REWARD_ID, // Rewarded ad placement ID
// scenarioKey = "your_scenario_key", // Optional, for scenario statistics
// userId = "user_123", // Optional, user ID for server-side reward verification
// customData = mapOf("key" to "value"), // Optional, custom data passed to the ad server
)
// Obtain the rewarded ad object via the UjuAdObject factory method
rewardAd = UjuAdObject.getRewardObject(activity, adConfig)
// Set the ad listener to monitor various ad events
rewardAd?.setAdObjectListener(object : RewardAdObjectListener {
/**
* Ad load success callback
*
* @param placementId Placement ID
*/
override fun onLoadSuccess(placementId: String) {
// Ad loaded successfully, can now display; recommend checking isReady before showing
logger.add("Reward: onLoadSuccess")
}
/**
* Ad load failure callback
*
* @param error Error information
* @param placementId Placement ID
*/
override fun onLoadError(
error: UjuException,
placementId: String
) {
// Load failed, log the error
logger.add("Reward: onLoadError:${error.message}")
}
/**
* Ad display success callback
*/
override fun onAdShow() {
// Get ad info, log the ecpm value
val ecpm = rewardAd?.getAdInfo()?.ecpm
logger.add("Reward: onAdShow: ecpm:$ecpm")
}
/**
* Ad display error callback
*
* @param error Error information
*/
override fun onAdError(
error: UjuException
) {
// Log the ad error
logger.add("Reward: onAdError:${error.message}")
}
/**
* Ad playback complete callback
*/
override fun onAdPlayComplete() {
// Log the ad playback complete event
logger.add("Reward: onAdPlayComplete")
}
/**
* Ad clicked callback
*/
override fun onAdClicked() {
// Log the ad click event
logger.add("Reward: onAdClicked")
}
/**
* User skipped video callback
*/
override fun onAdSkippedVideo() {
// Log the user skipped video event
logger.add("Reward: onAdSkippedVideo")
}
/**
* Reward arrived callback
*
* Triggered when the user finishes watching the ad; grant the reward here
*/
override fun onAdRewardArrived() {
// Log the reward arrived event
logger.add("Reward: onAdRewardArrived")
// Note: In a real app, grant the reward to the user in this callback
}
/**
* Ad closed callback
*/
override fun onAdClosed() {
// Destroy the ad object and release resources
rewardAd?.destroy()
rewardAd = null
// Log the ad close event
logger.add("Reward: onAdClosed")
}
})
// Start loading the ad
rewardAd?.load()
// Log the load ad event
logger.add("Reward: load, placementId:${adConfig.placementId}")
}
/**
* Display the rewarded ad
*
* Before displaying, checks whether the ad is ready
* Only calls show() when the ad state is ready
*/
fun show() {
// Check if the ad is ready
if (rewardAd?.isReady() == true) {
// Ad is ready, display it
rewardAd?.show(activity)
} else {
// Ad not ready, log it
logger.add("Reward: ad not ready")
}
}
/**
* Check if the ad is loaded
*
* @return true means the ad object has been created, false means not created
* Note: This method only checks whether the ad object exists, not whether it is ready
* To check if the ad can be displayed, use the isReady() method
*/
fun isLoaded(): Boolean {
return rewardAd != null
}
/**
* Destroy the ad object
*
* Call this method when the ad is no longer needed to destroy the ad object and release resources
*/
fun destroy() {
// Destroy the ad object
rewardAd?.destroy()
// Null out the ad object reference
rewardAd = null
}
}UjuAdConfig Configuration
| Parameter | Type | Required | Description |
|---|---|---|---|
placementId | String | Yes | Placement ID |
scenarioKey | String | No | Ad display scenario key, used for scenario statistics |
userId | String | No | User ID, for server-side reward verification (recommended to pass in for server-side reward validation) |
customData | Map<String, String> | No | Custom data, passed through to the ad server, can be used for reward callback validation |
adViewSize | AdViewSize | No | Ad size (generally not needed for rewarded video) |
2. Display the Rewarded Video Ad
When the user triggers the ad-watching behavior (e.g., clicks a "Watch ad for reward" button), display the ad:
fun show() {
if (rewardAd?.isReady() == true) {
rewardAd?.show(activity)
} else {
logger.add("Reward: ad not ready")
}
}3. Grant the Reward
Grant the developer-predefined reward directly in the onAdRewardArrived() callback. The SDK does not return reward type/amount; the reward logic is customized by the developer:
// Implement the reward callback in RewardAdObjectListener
override fun onAdRewardArrived() {
// SDK does not return reward type/amount; developer grants the predefined reward here
// For example: grant a fixed number of coins
userCoins += 100
updateCoinsDisplay()
// Show reward notification
showRewardToast("Earned 100 coins")
}4. Ad Lifecycle Management
The SDK internally handles foreground/background switching and video pause/resume via AppLifecycleObserver; developers do not need to manually call pause()/resume(). Only release ad resources when the Activity is destroyed:
/**
* Called when the Activity is destroyed
*
* Destroy the ad here to release resources and avoid memory leaks
*/
override fun onDestroy() {
super.onDestroy()
// Destroy the ad
if (rewardAd != null) {
rewardAd?.destroy()
rewardAd = null
}
}Best Practices
1. Ad Trigger Timing
- After game level failure: Offer an option to watch an ad to continue
- When resources are low: Offer watching an ad for extra resources
- Before unlocking content: Offer watching an ad to unlock premium content
- Daily rewards: Offer watching an ad for extra daily rewards
2. Optimization Tips
- Preload ads: Load ads before they need to be displayed
- Ad state check: Check if the ad is loaded before displaying
- Reward granting: Ensure the reliability of reward granting
- User experience: Provide clear reward notifications
- Frequency control: Avoid over-displaying ads
3. Pitfalls to Avoid
- Do not force ads during critical user actions
- Do not falsely advertise rewards
- Do not affect normal app functionality when ad loading fails
- Do not grant rewards before the user finishes watching
FAQ
Q: Why is the rewarded video ad not showing?
A: Possible reasons:
- Incorrect ad unit ID
- Network connection issue
- Insufficient ad inventory
- Ad not finished loading
- Device restrictions
Q: How to ensure the reliability of reward granting?
A: Recommendations:
- Grant rewards in the
onAdRewardArrivedcallback - Verify reward validity on the server side
- Store reward records locally to prevent accidents
- Provide a retry mechanism for reward grant failures
Q: How to improve rewarded video ad revenue?
A: Recommendations:
- Choose appropriate ad trigger timing
- Provide attractive rewards
- Optimize ad display frequency
- Ensure ads are relevant to app content
- Increase app user engagement
