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!