Flutter Sdk: 3.27.1 google_mobile_ads: ^6.0.0
0
I am facing this issue on Samsung F23, Android 14, API 34 when the app starts I display the Ad on the Home Screen and that is working well but when I navigate to the other page where I place the Ad that one is making problems Sometimes it shows, and sometimes it does not.
However, the Ad is clickable, so each time I tap on the white space, it opens the advertiser's link.
Here you can see the Screen Shots
package xxx.xxx.app import android.view.LayoutInflater import android.view.View import android.widget.Button import android.widget.ImageView import android.widget.RatingBar import android.widget.TextView import com.google.android.gms.ads.nativead.NativeAd import com.google.android.gms.ads.nativead.NativeAdView import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory import androidx.browser.customtabs.CustomTabsIntent import android.content.ActivityNotFoundException import android.net.Uri import android.widget.Toast import io.flutter.plugin.common.MethodChannel class MainActivity: FlutterActivity() { private val CHANNEL = "browser_launcher" private var browserLaunched = false override fun configureFlutterEngine(flutterEngine: FlutterEngine) { flutterEngine.plugins.add(GoogleMobileAdsPlugin()) super.configureFlutterEngine(flutterEngine) // Register native ad factories GoogleMobileAdsPlugin.registerNativeAdFactory( flutterEngine, "NativeMedium", MediumNativeAdFactory(layoutInflater)) GoogleMobileAdsPlugin.registerNativeAdFactory( flutterEngine, "NativeSmall", SmallNativeAdFactory(layoutInflater)) // Set up method channel for custom tabs MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "launchCustomTabs" -> { val url = call.argument<String>("url") if (url != null) { try { val customTabsIntent = CustomTabsIntent.Builder().build() customTabsIntent.intent.data = Uri.parse(url) browserLaunched = true // Notify Flutter before launching browser MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) .invokeMethod("onBrowserLaunching", null) startActivity(customTabsIntent.intent) result.success(null) } catch (e: ActivityNotFoundException) { Toast.makeText( this, "No browser found to open the URL", Toast.LENGTH_LONG ).show() result.error("BROWSER_NOT_FOUND", "No browser found to open the URL", null) } } else { result.error("INVALID_URL", "URL cannot be null", null) } } else -> { result.notImplemented() } } } } override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) { GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "NativeMedium") GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "NativeSmall") } override fun onResume() { super.onResume() if (browserLaunched) { browserLaunched = false // Notify Flutter that we're back from the browser flutterEngine?.dartExecutor?.binaryMessenger?.let { messenger -> MethodChannel(messenger, CHANNEL).invokeMethod("onBrowserClosed", null) } } } } class MediumNativeAdFactory: NativeAdFactory { private var layoutInflater: LayoutInflater constructor(layoutInflater: LayoutInflater) { this.layoutInflater = layoutInflater } override fun createNativeAd(nativeAd: NativeAd?, customOptions: MutableMap<String, Any>?): NativeAdView { val adView = layoutInflater.inflate(R.layout.my_native_ad, null) as NativeAdView // Set the media view. adView.mediaView = adView.findViewById(R.id.ad_media) // Hide MediaView if no mediaContent to avoid blank space if (nativeAd?.mediaContent == null) { adView.mediaView?.visibility = View.GONE } else { adView.mediaView?.visibility = View.VISIBLE } // Set other ad assets. adView.headlineView = adView.findViewById(R.id.ad_headline) adView.bodyView = adView.findViewById(R.id.ad_body) adView.callToActionView = adView.findViewById(R.id.ad_call_to_action) adView.iconView = adView.findViewById(R.id.ad_app_icon) adView.starRatingView = adView.findViewById(R.id.ad_stars) val advertiserView: TextView? = adView.findViewById(R.id.ad_advertiser) // The headline is guaranteed to be in every NativeAd. (adView.headlineView as TextView).text = nativeAd?.headline adView.mediaView?.mediaContent = nativeAd?.mediaContent // These assets aren't guaranteed to be in every NativeAd, so it's important to // check before trying to display them. if (nativeAd?.body == null) { adView.bodyView?.visibility = View.INVISIBLE } else { adView.bodyView?.visibility = View.VISIBLE (adView.bodyView as TextView).text = nativeAd.body } if (advertiserView != null) { val advertiser = nativeAd?.advertiser if (advertiser.isNullOrBlank()) { advertiserView.visibility = View.GONE } else { advertiserView.text = advertiser advertiserView.visibility = View.VISIBLE } } if (nativeAd?.callToAction == null) { adView.callToActionView?.visibility = View.INVISIBLE } else { adView.callToActionView?.visibility = View.VISIBLE (adView.callToActionView as Button).text = nativeAd.callToAction } if (nativeAd?.icon == null) { adView.iconView?.visibility = View.GONE } else { (adView.iconView as ImageView).setImageDrawable(nativeAd.icon!!.drawable) adView.iconView?.visibility = View.VISIBLE } if (nativeAd?.starRating == null) { adView.starRatingView?.visibility = View.GONE } else { (adView.starRatingView as RatingBar).rating = nativeAd.starRating!!.toFloat() adView.starRatingView?.visibility = View.VISIBLE } // Advertiser already bound above using advertiserView // This method tells the Google Mobile Ads SDK that you have finished populating your // native ad view with this native ad. if (nativeAd != null) { adView.setNativeAd(nativeAd) } return adView } } class SmallNativeAdFactory: NativeAdFactory { private var layoutInflater: LayoutInflater constructor(layoutInflater: LayoutInflater) { this.layoutInflater = layoutInflater } override fun createNativeAd(nativeAd: NativeAd?, customOptions: MutableMap<String, Any>?): NativeAdView { val adView = layoutInflater.inflate(R.layout.native_small, null) as NativeAdView // Set other ad assets. adView.headlineView = adView.findViewById(R.id.ad_headline) adView.bodyView = adView.findViewById(R.id.ad_body) adView.callToActionView = adView.findViewById(R.id.ad_call_to_action) adView.iconView = adView.findViewById(R.id.ad_app_icon) adView.starRatingView = adView.findViewById(R.id.ad_stars) val advertiserView: TextView? = adView.findViewById(R.id.ad_advertiser) // The headline is guaranteed to be in every NativeAd. (adView.headlineView as TextView).text = nativeAd?.headline // These assets aren't guaranteed to be in every NativeAd, so it's important to // check before trying to display them. if (nativeAd?.body.isNullOrBlank()) { adView.bodyView?.visibility = View.GONE } else { adView.bodyView?.visibility = View.VISIBLE (adView.bodyView as TextView).text = nativeAd.body } // Advertiser is already handled above if (nativeAd?.callToAction.isNullOrBlank()) { adView.callToActionView?.visibility = View.GONE } else { adView.callToActionView?.visibility = View.VISIBLE (adView.callToActionView as Button).text = nativeAd.callToAction } if (nativeAd?.icon == null) { adView.iconView?.visibility = View.GONE } else { (adView.iconView as ImageView).setImageDrawable(nativeAd.icon!!.drawable) adView.iconView?.visibility = View.VISIBLE } if (nativeAd?.starRating == null) { adView.starRatingView?.visibility = View.GONE } else { (adView.starRatingView as RatingBar).rating = nativeAd.starRating!!.toFloat() adView.starRatingView?.visibility = View.VISIBLE } if (advertiserView != null) { val advertiser = nativeAd?.advertiser if (advertiser.isNullOrBlank()) { advertiserView.visibility = View.GONE } else { advertiserView.text = advertiser advertiserView.visibility = View.VISIBLE } } // This method tells the Google Mobile Ads SDK that you have finished populating your // native ad view with this native ad. if (nativeAd != null) { adView.setNativeAd(nativeAd) } return adView } } ///load native ad Future<void> loadGoogleBannerAds(String adGoogleUnitId) async { await _googleNativeAd?.dispose(); _googleNativeAd = NativeAd( adUnitId: adGoogleUnitId, request: const AdRequest(), factoryId: 'NativeSmall', listener: NativeAdListener( onAdLoaded: (ad) { print('AD onAdLoaded'); if (mounted) { setState(() { _googleNativeAd = ad as NativeAd; valueSet.value = BannerShimmerValue.success; }); } else { ad.dispose(); } }, onAdFailedToLoad: (ad, err) { print('AD onAdFailedToLoad'); ad.dispose(); if (mounted) { setState(() { _googleNativeAd = null; }); } loadGoogleBannerFailedAds(); }, onAdOpened: (Ad ad) {}, onAdClosed: (Ad ad) {}, onAdImpression: (Ad ad) { print('AD Impression'); }, ), )..load(); } ///show native ad if (_googleNativeAd != null) { print('_googleNativeAd != null'); return SizedBox( height: 100, width: MediaQuery.of(context).size.width, // full width child: AdWidget(key: ValueKey(_googleNativeAd), ad: _googleNativeAd!), ); } 
