Home > Net >  An issue with App Open Ads in Kotlin | Android
An issue with App Open Ads in Kotlin | Android

Time:07-03

App Open Ads-

I want to show ads with the first launch "onStart() function" but, The problem is that the Ads don't show in the first launch (onStart() function) it shows in the onResume() function after I exit the application and resume it.

Are there any Suggestions or Editing Guys?

MyApplication Class

class MyApplication : Application() {

private var appOpenManager: AppOpenManager? = null
 override fun onCreate() {
    super.onCreate()

    MobileAds.initialize(this) {
        Log.d("tag", "MobileAds init ")
    }
    appOpenManager = AppOpenManager(this)
    ProcessLifecycleOwner.get().lifecycle.addObserver(appOpenManager!!.defaultLifecycleObserver)

 }
}

AppOpenManager Class

class AppOpenManager(private val myApplication: MyApplication) :
    Application.ActivityLifecycleCallbacks,
    LifecycleObserver {


    private var appOpenAd: AppOpenAd? = null
    private var loadCallback: AppOpenAd.AppOpenAdLoadCallback? = null
    private var currentActivity: Activity? = null
    private var isShowingAd = false
    private val adRequest: AdRequest
        get() = AdRequest.Builder().build()

    private val isAdAvailable: Boolean
        get() = appOpenAd != null

    companion object {
        private const val AD_UNIT_ID = "ca-app-pub-3940256099942544/3419835294" //test id
    }
    
    init {
        myApplication.registerActivityLifecycleCallbacks(this)
    }


    private fun fetchAd() {
        if (isAdAvailable) {
            return
        } else {
            Log.d("tag", "fetching... ")
            loadCallback = object : AppOpenAd.AppOpenAdLoadCallback() {

                override fun onAdFailedToLoad(p0: LoadAdError) {
                    super.onAdFailedToLoad(p0)
                    Log.d("tag", "onAppOpenAdFailedToLoad: ")
                }

                override fun onAdLoaded(ad: AppOpenAd) {
                    super.onAdLoaded(ad)
                    appOpenAd = ad
                    Log.d("tag", "isAdAvailable = true")
                }
            }
            val request = adRequest
            AppOpenAd.load(
                myApplication,
                AD_UNIT_ID,
                request,
                AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
                loadCallback!!
            )
        }
    }

    fun showAdIfAvailable() {
        Log.d("tag", "$isShowingAd - $isAdAvailable")

        if (!isShowingAd && isAdAvailable) {
            Log.d("tag", "will show ad ")
            val fullScreenContentCallback: FullScreenContentCallback =
                object : FullScreenContentCallback() {

                    override fun onAdDismissedFullScreenContent() {
                        appOpenAd = null
                        isShowingAd = false
                        fetchAd()
                    }

                    override fun onAdFailedToShowFullScreenContent(p0: AdError) {

                    }

                    override fun onAdShowedFullScreenContent() {
                        isShowingAd = true
                    }
                }
            appOpenAd!!.fullScreenContentCallback = fullScreenContentCallback
            appOpenAd!!.show(currentActivity!!)
        } else {
            Log.d("tag", "can't show ad ")
            fetchAd()
        }
    }

    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        currentActivity = activity
    }

    override fun onActivityStarted(activity: Activity) {
        currentActivity = activity
    }

    override fun onActivityResumed(activity: Activity) {
        currentActivity = activity
    }

    override fun onActivityPaused(activity: Activity) {

    }

    override fun onActivityStopped(activity: Activity) {

    }

    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
        currentActivity = activity
    }

    override fun onActivityDestroyed(activity: Activity) {
        currentActivity = null
    }


    var defaultLifecycleObserver = object : DefaultLifecycleObserver {
        override fun onStart(owner: LifecycleOwner) {
            super.onStart(owner)
            Log.d("tag", "onStart()")
            showAdIfAvailable()
        }

        override fun onCreate(owner: LifecycleOwner) {
            super.onCreate(owner)
            Log.d("tag", "onCreate() ")

        }
    }

}

CodePudding user response:

onStart calls showAdIfAvailable() which only shows one if isAdAvailable is true, but it's initialised as false - so it calls fetchAd() instead. All that does is store an ad (so isAdAvailable is true for the next time you hit onStart).

Maybe you want to call showAdIfAvailable() again from your success callback when you fetch one?

override fun onAdLoaded(ad: AppOpenAd) {
    super.onAdLoaded(ad)
    appOpenAd = ad
    Log.d("tag", "isAdAvailable = true")
    // you got an ad - try and display it
    showAdIfAvailable()
}

Just be careful, because your ads are being fetched asynchronously, it's possible your Activity could be destroyed while that request is still ongoing. That means you'd set currentActivity to null, your fetch would succeed and run showAdIfAvailable, and that tries to use currentActivity.

You need to null-check that - none of this !! stuff

if (!isShowingAd && isAdAvailable) {
    val fullScreenContentCallback = object : FullScreenContentCallback() {
        ...
    }
    // ensure neither of these are null -while we're using them-
    // let and run basically create new variables that can't be changed by callbacks etc
    currentActivity?.let { activity ->
        appOpenAd?.run {
            fullScreenContentCallback = fullScreenContentCallback
            show(activity)
    }
}

Not necessarily the most elegant way (it would be better to null-check first so you don't do anything you don't need to, like creating that callback object which might not be used) but I don't want to rewrite your code. You get the idea hopefully!

  • Related