Android Admob RewardedVideoAd: Complete Guide with Error Handling

Aug 29, 2019

Setup AdMob for Android With Firebase

Initialize the SDK

Only need to be done once, probably at Application.

class LuaApp: Application() {    override fun onCreate() {        super.onCreate()        MobileAds.initialize(this, "[ADMOB_APP_ID]")    }}

Create Ad Unit

Goto https://apps.admob.com/, click Apps -> Your App -> Add Ad Unit.

  • Select ad format: Rewarded
  • Name
  • Reward settings: e.g. reward amount = 1, reward item = ExtraLive (just a amount and string which shall be returned in a callback upon successful watching on an ad video)
  • Create ad Unit
  • Copy Ad Unit ID

Load Ad

I am using a DialogFragment.

class GiftDialog : DialogFragment() {    companion object {        private const val FRAGMENT_TAG = "gift_dialog"        fun newInstance() = GiftDialog()        fun show(fragmentManager: FragmentManager): GiftDialog {            val dialog = newInstance()            // dialog.isCancelable = false            dialog.show(fragmentManager, FRAGMENT_TAG)            return dialog        }    }    private lateinit var ad: RewardedVideoAd    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        // full screen like an activity        setStyle(STYLE_NORMAL, android.R.style.Theme_DeviceDefault_Light_NoActionBar)    }    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {        // return super.onCreateView(inflater, container, savedInstanceState)        return activity!!.layoutInflater.inflate(R.layout.gift, container)    }    override fun onActivityCreated(savedInstanceState: Bundle?) {        super.onActivityCreated(savedInstanceState)        ad = MobileAds.getRewardedVideoAdInstance(context)        ad.rewardedVideoAdListener = object : RewardedVideoAdListener {            override fun onRewardedVideoAdClosed() {                // if need to re-use to load more than 1 ad                // loadAd()            }            override fun onRewardedVideoAdLeftApplication() {            }            override fun onRewardedVideoAdLoaded() {            }            override fun onRewardedVideoAdOpened() {            }            override fun onRewardedVideoCompleted() {            }            override fun onRewarded(reward: RewardItem) {                // handle reward                Toast.makeText(context, "reward=${reward.type} x ${reward.amount}", Toast.LENGTH_LONG).show()            }            override fun onRewardedVideoStarted() {            }            override fun onRewardedVideoAdFailedToLoad(errorCode: Int) {                // don't show error here, only when user click show ad button                /*                // https://developers.google.com/android/reference/com/google/android/gms/ads/AdListener                val message = when (errorCode) {                    AdRequest.ERROR_CODE_NETWORK_ERROR -> "Make sure you have network for Ads to be loaded"                    AdRequest.ERROR_CODE_NO_FILL -> "No Ads available"                    else -> "Load Ads Failed ($errorCode)"                }                Toast.makeText(context, message, Toast.LENGTH_LONG).show()                 */                // use customData to store error code                ad.customData = errorCode.toString()            }        }        // preload ad        loadAd()        showAdButton.setOnClickListener {            if (ad.isLoaded) {                ad.show()            }            else {                val message = if (ad.customData == null) {                    "Ads is not loaded, try again later"                }                else {                    val errorCode = ad.customData.toInt()                    when (errorCode) {                        AdRequest.ERROR_CODE_NETWORK_ERROR -> "Make sure you have network for Ads to be loaded"                        AdRequest.ERROR_CODE_NO_FILL -> "No Ads available"                        else -> "Load Ads failed ($errorCode)"                    }                }                // Toast.makeText(context, message, Toast.LENGTH_LONG).show()                AlertDialog.Builder(context)                    .setMessage("$message\nTry again?")                    .setPositiveButton(android.R.string.ok) { _, _ ->                        // might not be the best solution as the user might need to click a few times                        // listen to network connected event perhaps?                        loadAd()                    }                    .setNegativeButton(android.R.string.cancel, null)                    .show()            }        }    }    override fun onPause() {        super.onPause()        ad.pause(context)    }    override fun onResume() {        super.onResume()        ad.resume(context)    }    override fun onDestroy() {        super.onDestroy()        ad.destroy(context)    }    fun loadAd() {        // reset customData        ad.customData = null        // load debug ad during DEBUG        val adUnitId = if (BuildConfig.DEBUG) "ca-app-pub-3940256099942544/5224354917" else "ca-app-pub-8122************/**********"        ad.loadAd(adUnitId, AdRequest.Builder().build())    }}

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.