Skip to content

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:

kotlin
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 ​

ParameterTypeRequiredDescription
placementIdStringYesPlacement ID
scenarioKeyStringNoAd display scenario key, used for scenario statistics
userIdStringNoUser ID, for server-side reward verification (recommended to pass in for server-side reward validation)
customDataMap<String, String>NoCustom data, passed through to the ad server, can be used for reward callback validation
adViewSizeAdViewSizeNoAd 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:

kotlin
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:

kotlin
// 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:

kotlin
/**
 * 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 onAdRewardArrived callback
  • 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