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