androidandroid-jetpack-composeadmob

Ad banner with Jetpack compose not loading ads


I am trying to add an ad banner to my Jetpack compose app. I am using AdMob but no ads are displayed:

enter image description here

I created an AdBanner() composable:

@Composable
private fun AdBanner() {
    AndroidView(
        modifier = Modifier.fillMaxWidth(),
        factory = { context ->
            AdView(context).apply {
                setAdSize(AdSize.BANNER)
                adUnitId = context.getString(R.string.banner_ad_unit_id)
                loadAd(
                    AdRequest
                        .Builder()
                        .build()
                )
            }
        }
    )
}

I initialize ads in MainActivity.onCreate():

        val backgroundScope = CoroutineScope(Dispatchers.IO)
        backgroundScope.launch {
            // Initialize the Google Mobile Ads SDK on a background thread.
            Log.d(
                "MainActivity",
                "Initializing Google Mobile Ads SDK..."
            )
            MobileAds.initialize(this@MainActivity) {}
        }

I checked and double checked that my application id is set correctly in a <metadata> tag in AndroidManifest.xml and that my ad unit id is correct. What else can I check to troubleshoot this?

Edit (additional information):

  1. I'm using a test ad unit with the Fixed Sized Banner id from here:
        <string name="banner_ad_unit_id">ca-app-pub-3940256099942544/6300978111</string>
    
  2. I added my phone as a test device to my Ad Mob account. I set up a shake gesture to view Ad Inspector which shows ads are not filled:

enter image description here

  1. Logcat shows one error:

    Invalid ID 0x00000000.

    This doesn't seem very helpful since there is absolutely no additional information. There isn't even enough information to determine if this is an error with the ad banner or something else entirely.

  2. I added an AdListener:

    object : AdListener() {
                    override fun onAdFailedToLoad(p0: LoadAdError) {
                        Log.d(
                            "AdBanner",
                            "Failed to load ad: ${p0.message}"
                        )
                    }
    
                    override fun onAdLoaded() {
                        Log.d(
                            "AdBanner",
                            "Ad loaded"
                        )
                    }
    
                    override fun onAdClicked() {
                        Log.d(
                            "AdBanner",
                            "Ad clicked"
                        )
                    }
    
                    override fun onAdClosed() {
                        Log.d(
                            "AdBanner",
                            "Ad closed"
                        )
                    }
    
                    override fun onAdImpression() {
                        Log.d(
                            "AdBanner",
                            "Ad impression"
                        )
                    }
    
                    override fun onAdOpened() {
                        Log.d(
                            "AdBanner",
                            "Ad opened"
                        )
                    }
    
                    override fun onAdSwipeGestureClicked() {
                        Log.d(
                            "AdBanner",
                            "Ad swipe gesture clicked"
                        )
                    }
                }
    

    This gives output like the following:

    Ad loaded Ad impression

    This looks reasonable and what I would expect when ads load. There is no output from the onAdFailedToLoad().

On a side note, the Get Started Guide doesn't mention requesting internet permissions, but it seems like this is needed. I added it to AndroidManifest.xml, but still no luck:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Edit 2:

I'm using the AdBanner() composable like this:

    Scaffold(
        // ...
    ) { innerPadding ->
        Column(modifier = Modifier.fillMaxSize()) {
            AdBanner()

            BaseballCardList(
                navController = navController,
                cards = stateList,
                onCardChanged = { index, card -> stateList[index] = card },
                contentPadding = innerPadding
            )

        // ...

    }

Solution

  • Turns out that it was a layout issue, not a problem with using the AdMob SDK. I ended up modifying the Column() that surrounds my AdBanner() with something like this:

        Scaffold(/* ... */) { innerPadding ->
            Column(modifier = Modifier.padding(innerPadding)) {
                AdBanner()
            }
        }