I just upgraded from Admob 20.6.0 to 21.4.0 in an Android project. Up until the upgrade, Admob App Open ads were working as expected. In 21.4.0 I am getting an error in showAdIfAvailable()
Type mismatch. Required: Activity Found: Activity?
On this line:
appOpenAd?.show(currentActivity)
Code correct suggests the following, but the problem is this code never runs.
currentActivity?.let { appOpenAd?.show(it) }
Here's the full code for AppOpenManager:
class AppOpenManager(private val myApplication: MainActivity) : DefaultLifecycleObserver, Application.ActivityLifecycleCallbacks {
private var appOpenAd: AppOpenAd? = null
private var loadCallback: AppOpenAdLoadCallback? = null
private var currentActivity : Activity? = null
private var isShowingAd : Boolean = false
private var loadTime:Long = 0
/** Creates and returns ad request. */
private fun getAdRequest():AdRequest {
return AdRequest.Builder().build()
}
/** Utility method that checks if ad exists and can be shown. */
private fun isAdAvailable():Boolean {
return appOpenAd != null && wasLoadTimeLessThan4HoursAgo()
}
/** Constructor */
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
this.myApplication.registerActivityLifecycleCallbacks(this)
}
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
/** Request an ad */
fun fetchAd() {
if (isAdAvailable()) {
// Have unused ad, no need to fetch another.
return
}
loadCallback = object : AppOpenAdLoadCallback() {
override fun onAdLoaded(ad: AppOpenAd) {
this@AppOpenManager.appOpenAd = ad
this@AppOpenManager.loadTime = (Date()).time
}
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
println("onAppOpenAdFailedToLoad $loadAdError")
}
}
val request: AdRequest = getAdRequest()
AppOpenAd.load(myApplication, StaticData.appOpenID, request, AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, loadCallback as AppOpenAdLoadCallback)
}
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
showAdIfAvailable()
println("onStart")
}
private fun showAdIfAvailable() {
// Only show ad if there is not already an app open ad currently showing and an ad is available.
if (!isShowingAd && isAdAvailable()){
println("Will show ad.")
val fullScreenContentCallback = object: FullScreenContentCallback() {
override fun onAdDismissedFullScreenContent() {
// Set the reference to null so isAdAvailable() returns false.
this@AppOpenManager.appOpenAd = null
isShowingAd = false
fetchAd()
}
override fun onAdFailedToShowFullScreenContent(adError: AdError) {}
override fun onAdShowedFullScreenContent() {
isShowingAd = true
}
}
appOpenAd?.fullScreenContentCallback = fullScreenContentCallback
appOpenAd?.show(currentActivity) // Type mismatch. Required: Activity Found: Activity?
}
else
{
println("Can not show ad... FETCH ONE INSTEAD!")
fetchAd()
}
}
/** Utility method to check if ad was loaded more than n hours ago. */
private fun wasLoadTimeLessThan4HoursAgo():Boolean {
val dateDifference = (Date()).time - this.loadTime
val numMilliSecondsPerHour:Long = 3600000
return (dateDifference < (numMilliSecondsPerHour * 4))
}
override fun onActivityPaused(activity: Activity) {
println("⚠️ onActivityPaused")
}
override fun onActivityStarted(activity: Activity) {
println("⚠️ onActivityStarted")
currentActivity = activity
}
override fun onActivityDestroyed(activity: Activity) {
println("⚠️ onActivityDestroyed")
currentActivity = null
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
println("⚠️ onActivitySaveInstanceState")
}
override fun onActivityStopped(activity: Activity) {
println("⚠️ onActivityStopped")
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
println("⚠️ onActivityCreated")
}
override fun onActivityResumed(activity: Activity) {
println("⚠️ onActivityResumed")
currentActivity = activity
}
}
And in MainActivity:
private var appOpenManager: AppOpenManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...
appOpenManager = AppOpenManager(this)
}
How do I get Android Admob App Open Ads to show in 21.4.0
Type mismatch. Required: Activity Found: Activity?
this error came because they made a major change
Added @NonNull annotations in every method that previously did not explicitly define nullability. -- in 21.0.0
but the problem is this code never runs
currentActivity?.let { appOpenAd?.show(it) }
That is a correct way to solve the above error. I'll assume here that currentActivity
is null or addOpenAd
is null so the show(it)
function call doesn't happen. Without logcat it's hard to see the root cause is, but here are a few things to check. I think one of these will be the solution:
onAdFailedToLoad
doesn't get called by looking for the log line. This will make sure that appOpenAd
is assigned.currentActivity
will never get assigned. Because the lifecycle callbacks from registerActivityLifecycleCallbacks
will not be registered.appOpenAd = null, currentActivity = null
)appOpenAd = null, currentActivity = !null
)showAdIfAvailable
is called, but there's no ad yetonAdLoaded