flutterprovidergoogle-mobile-ads

Admob banner ad shows only when changing from one drawer page to the ad-page in Flutter app?


The following is a minimal code to my Android app where I'm trying to show an Admob banner ad at the bottom of my home page.

The external packages needed are google_mobile_ads and provider available to install from the pub.dev website. I have these with the latest version from the website. My Flutter version is the latest stable version 3.22.2.

The Problem:

In my actual app: In my actual app, with these code below, the ad loads with the message logged to the console, but does not get displayed at the bottom of the screen (or anywhere). When I move to another page using the Drawer navigation, and then again go back to the page with the banner ad, the ad then shows up. It is also notable that there are no log messages of the ad being closed when I navigate to another page. I don't know if that behaviour is expected. However, since this way the banner ad shows up, I'm sure there is something correct with the code, and something else is not, since displaying the app needs additional steps in usage of the app by the user. Also noted is that when navigating to another page using the TextButton which I've facilitated, and back to the page with banner ad, the ad doesn't show up. The showing up happens only when navigating to another page and back using the drawer pages.

In this minimal app: I've created here a minimal app, and put the same code used for integrating the Admob banner ad as done in my actual app, here in a single page. The code for displaying the banner ad has not changed but the behaviour of the app has. With the following code, I've not managed the app to get running, even. The installing of debug app seems to take infinite amount of time so I had to stop it.

I hope someone is able to help me with this code, and also fix the problem with my actual app.

UPDATE:

The problem of debug code taking infinite time to install was probably due to improper formatting of my AndroidManifest.xml file which I've fixed and the minimal app now loads properly. The problem is still the same. There is "App loaded" message in the log, but the banner ad does not show up, not even when pressing the hot reload/restart button. But, the ad does show up whenever I save the main.dart file with Ctrl+S.

The minimal code:

import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:provider/provider.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();

  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider<AdsProvider>(
          create: (context) => AdsProvider(),
        ),
      ],
      child: const MyApp(),
    ),
  );
}

// AdIntegration classes: START:

class AdsHelper {
  static String bannerHomePage() {
    if (Platform.isAndroid) {
      // for the timebeing, using a test ad unit as follows:
      return "ca-app-pub-3940256099942544/9214589741";
    } else {
      return "";
    }
  }
}

class AdsProvider with ChangeNotifier {
  bool isBannerHomePageLoaded = false;
  late BannerAd bannerHomePage;

  void initializeBannerHomePage() async {
    bannerHomePage = BannerAd(
      size: AdSize.banner,
      adUnitId: AdsHelper.bannerHomePage(),
      listener: BannerAdListener(
        onAdLoaded: (ad) {
          isBannerHomePageLoaded = true;
          log("HomePage BannerAd loaded!");
        },
        onAdClosed: (ad) {
          ad.dispose();
          isBannerHomePageLoaded = false;
        },
        onAdFailedToLoad: (ad, err) {
          isBannerHomePageLoaded = false;
          log(err.toString());
        },
      ),
      request: AdRequest(),
    );
    await bannerHomePage.load();
    notifyListeners();
  }
}

// AdIntegration classes: END.

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        scaffoldBackgroundColor: const Color.fromARGB(255, 234, 153, 153),
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();

    /*
    Timer(const Duration(seconds: 2), () {
      // Initialize HomePage (DashboardPage) Banner Ad:
      AdsProvider adsProvider =
          Provider.of<AdsProvider>(context, listen: false);
      adsProvider.initializeBannerHomePage();
    });
    */

    // Initialize HomePage (DashboardPage) Banner Ad:
    AdsProvider adsProvider = Provider.of<AdsProvider>(context, listen: false);
    adsProvider.initializeBannerHomePage();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: ListView(
        children: [
          Text("Lable 01"),
          Text("Lable 02"),
          Text("Lable 03"),
          Text("Lable 04"),
        ],
      ),
      bottomNavigationBar: Consumer<AdsProvider>(
        builder: (context, adsProvider, child) {
          if (adsProvider.isBannerHomePageLoaded) {
            return Container(
              height: adsProvider.bannerHomePage.size.height.toDouble(),
              child: AdWidget(
                ad: adsProvider.bannerHomePage,
              ),
            );
          } else {
            return Container(
              height: 0,
            );
          }
        },
      ),
    );
  }
}

The AndroidManifest.xml file:

In the above minimal code, I've used test Ad Unit ID, and also added a test app ID to the AndroidManifest.xml file which is as follows:

<!-- AdMob app ID: (for the timebeing, using test app ID) -->
<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-3940256099942544~3347511713"/>

Solution

  • Add notifyListeners() inside onAdLoaded after isBannerHomePageLoaded = true; Same in other onAdClosed and onAdFailedToLoad

    This happend because page is not refresh after ad loaded. If you want to check that log data with isBannerHomePageLoaded variable.