【问题标题】:Flutter firebase_admob show only onceFlutter firebase_admob 只显示一次
【发布时间】:2019-02-04 12:54:12
【问题描述】:

以下代码在应用程序底部显示横幅广告,并在点击时显示插页式广告。按下按钮时显示插页式广告。问题是,当应用程序第一次启动并单击按钮时,会显示插页式广告,但从第二次开始就不会显示插页式广告。 没有错误,所有日志消息都显示成功。我的代码错误吗?我正在安卓设备上测试。

import 'package:firebase_admob/firebase_admob.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  final admobAppId = 'ca-app-pub-3940256099942544~3347511713';
  final bannerId = 'ca-app-pub-3940256099942544/6300978111';
  final interstitialId = 'ca-app-pub-3940256099942544/1033173712';

  BannerAd bannerAd;
  InterstitialAd interstitialAd;

  MyApp() {
    FirebaseAdMob.instance.initialize(appId: admobAppId);
    makeBannerAd();
    initInterstitialAd();
  }

  makeBannerAd() {
    bannerAd = BannerAd(
        adUnitId: bannerId,
        size: AdSize.smartBanner,
        listener: (MobileAdEvent me) {
          print('MobileAdEvent $me');
        });
    bannerAd
      ..load()
      ..show();
  }

  initInterstitialAd() {
    interstitialAd = InterstitialAd(
        adUnitId: interstitialId,
        listener: (MobileAdEvent me) {
          print(
              '========== Interstitial ad mobile ad event =========== \n $me');
          if (me == MobileAdEvent.closed) {
            print('Interstitial closed');
            loadInterstitialAd();
          }
        });
    loadInterstitialAd();
  }

  loadInterstitialAd() {
    interstitialAd.load().then((val) {
      if (val) {
        print('Interstitial ad loaded callback success');
      } else {
        print('Interstitial ad loaded callback failed');
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('AdMob plugin test'),
        ),
        body: Center(
          child: RaisedButton(
            child: Text('Show Interstitial!'),
            onPressed: () {
              interstitialAd.show().then((val) {
                if (val) {
                  print('Interstitial ad show callback success');
                } else {
                  print('Interstitial ad show callback fail');
                }
              });
            },
          ),
        ),
      ),
    );
  }
}

更新
以下是带有 dispose() 的代码。它最多显示 2 次。

class MyApp extends StatelessWidget {

  final admobAppId = 'ca-app-pub-3940256099942544~3347511713';
  final bannerId = 'ca-app-pub-3940256099942544/6300978111';
  final interstitialId = 'ca-app-pub-3940256099942544/1033173712';

  BannerAd bannerAd;
  InterstitialAd interstitialAd;
  MobileAdTargetingInfo mobileAdTargetingInfo;

  MyApp() {
    FirebaseAdMob.instance.initialize(appId: admobAppId);
    makeBannerAd();
    initInterstitialAd();
  }

  makeBannerAd() {
    bannerAd = BannerAd(
        adUnitId: bannerId,
        size: AdSize.smartBanner,
        listener: (MobileAdEvent me) {
          print('Banner => MobileAdEvent $me');
        });
    bannerAd
      ..load()
      ..show();
  }

  initInterstitialAd() {
    interstitialAd = InterstitialAd(
        adUnitId: interstitialId,
        listener: (MobileAdEvent me) {
          print(
              '========== Interstitial ad mobile ad event =========== $me');
          if (me == MobileAdEvent.closed) {
            print('Interstitial closed');
            interstitialAd.dispose().then((val){
              if(val){
                loadInterstitialAd();
              }else{
              }
            });
          } else if (me == MobileAdEvent.failedToLoad) {
            print('Interstitial failed to load');
            loadInterstitialAd();
          }
        });
    loadInterstitialAd();
  }

  loadInterstitialAd() {
    interstitialAd.load();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('AdMob plugin test'),
        ),
        body: Center(
          child: RaisedButton(
            child: Text('Show Interstitial!'),
            onPressed: () {
              interstitialAd.show();
            },
          ),
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: dart flutter admob interstitial


    【解决方案1】:

    我遇到了同样的问题,并使用 InterstitialAd 对象解决了它,如下所示:

    InterstitialAd myInterstitial() {
        return InterstitialAd(
          adUnitId: InterstitialAd.testAdUnitId,
          targetingInfo: targetingInfo,
          listener: (MobileAdEvent event) {
            if (event == MobileAdEvent.failedToLoad) {
              interstitialAd..load();
            } else if (event == MobileAdEvent.closed) {
              interstitialAd = myInterstitial()..load();
            }
          },
        );
      }
    @override
    void initState() {
        FirebaseAdMob.instance.initialize(appId: 
            FirebaseAdMob.testAppId);
        interstitialAd = myInterstitial()..load();
        super.initState();
    }
    @override
    void dispose() {
        interstitialAd?.dispose();
        super.dispose();
    }
    

    调用方法:

    interstitialAd
      ..load()
      ..show();
    

    据我了解,您可以在事件关闭时使用监听器递归调用初始InterstitialAd 对象。我的来源是Tensor Programming Youtube Channel他解释得比我好。

    【讨论】:

    • 这很好用!唯一有效且无需每次都处理的方法,这是一个荒谬的解决方案。这应该是公认的答案。
    【解决方案2】:

    我修改并修复了代码如下,我也发布在github issue。现在,只要按下按钮,就会显示广告。我测试了 10 多次,效果很好。似乎每次想要展示广告时都需要创建 InterstitialAd。但具体我不知道。如果有人知道原因,请解释一下。

    import 'package:flutter/material.dart';
    import 'package:firebase_admob/firebase_admob.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      BannerAd myBanner;
    
      MyApp() {
        FirebaseAdMob.instance.initialize(appId: FirebaseAdMob.testAppId);
        myBanner =
            BannerAd(adUnitId: BannerAd.testAdUnitId, size: AdSize.smartBanner);
        myBanner
          ..load()
          ..show();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text("Interstitial Ad test"),
            ),
            body: Center(
              child: RaisedButton(
                child: Text("Interstitial ad"),
                onPressed: () {
                  InterstitialAd interstitialAd = new InterstitialAd(
                      adUnitId: InterstitialAd.testAdUnitId,
                      listener: (MobileAdEvent e) {
                        print("Mobile ad event => $e");
                      });
                  interstitialAd.load().then((val) {
                    interstitialAd.show();
                  });
                },
              ),
            ),
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。解决方法很简单。

      只需使用interstitialAd.dispose() 处理广告,以便下次加载新的插页式广告。

      【讨论】:

      • 我将 dispose() 添加到回调函数关闭条件,它第二次起作用,但是当我第三次按下按钮时,它显示此错误“ 请求错误:不会发送请求,因为插页式对象有被使用了。”
      • 哦...你能分享一些代码或截图或任何东西吗?
      • 如果我不使用Statefull 小部件会怎样?
      【解决方案4】:

      请举例说明我的工作方式。 希望对你有帮助。

      void main() => runApp(MyApp());
      
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'Flutter Intersticial',
            navigatorKey: Get.key, // use get: ^1.6.3
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: MyHomePage(title: 'Flutter Intersticial'),
          );
        }
      }
      
      class MyHomePage extends StatefulWidget {
        MyHomePage({Key key, this.title}) : super(key: key);
        final String title;
      
        @override
        _MyHomePageState createState() => _MyHomePageState();
      }
      
      class _MyHomePageState extends State<MyHomePage> {
      
        InterstitialAd _interstitialAd;
      
        InterstitialAd createIntersticialAd(){
          return InterstitialAd(
            adUnitId: AD_MOB_AD_INTERSTICIAL_1_ID,
            targetingInfo: AdMobUtil.targetingInfo,
            listener: (MobileAdEvent event) {
              print("InterstitialAd event is $event");
              // Dispose InterstitialAd 
              if (event == MobileAdEvent.closed)
                 dispose();
            },
          );
        }
      
        @override
        void dispose() {
          //
          // dispose intersticialAd
          //
          _interstitialAd?.dispose();
          super.dispose();
        }
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    'Go to second page',
                  ),
                ],
              ),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                //
                // create intersticialAd and send by parameter
                //
                _interstitialAd ??= createIntersticialAd();
                Get.to(SecondPage(interstitialAd: _interstitialAd,));
              },
              tooltip: 'Go to Second page',
              child: Icon(Icons.arrow_forward),
            ), // This trailing comma makes auto-formatting nicer for build methods.
          );
        }
      }
      
      
      class SecondPage extends StatefulWidget {
        //
        // define intersticial  final
        //
        final InterstitialAd interstitialAd;
      
        const SecondPage({Key key, this.interstitialAd}) : super(key: key);
      
        @override
        _SecondPageState createState() => _SecondPageState();
      }
      
      class _SecondPageState extends State<SecondPage> {
      
        @override
        Widget build(BuildContext context) {
          return Container();
        }
      
        @override
        void dispose() {
          //
          // show intersticial ad
          //
          widget.interstitialAd..load()..show();
          super.dispose();
        }
      }
      

      当您从第二页返回时,横幅将打开。

      我用这个包导航:https://pub.dev/packages/get

      如果帮助标记为有用..;)

      【讨论】:

        【解决方案5】:

        这里可能会迟到,但这可能对未来的观众有所帮助。这是最有效和最好的方法,这样您就可以一个接一个地观看广告。对于所有类型的广告,我在这里给出了插页式广告和奖励式广告的示例,其他广告的逻辑相同。您还可以在此处了解如何在广告失败后再次加载广告。

        完整代码:

        InterstitialAd _interstitialAd;
          RewardedAd _rewardedAd;
        
              void interstitialAdload () {
                InterstitialAd.load(
                    adUnitId: '<test ad>',
                    request: AdRequest(),
                    adLoadCallback: InterstitialAdLoadCallback(
                      onAdLoaded: (InterstitialAd ad) {
                        // Keep a reference to the ad so you can show it later.
                        this._interstitialAd = ad;
                        ad.fullScreenContentCallback = FullScreenContentCallback(
                          onAdShowedFullScreenContent: (InterstitialAd ad) =>
                              print('$ad onAdShowedFullScreenContent.'),
                          onAdDismissedFullScreenContent: (InterstitialAd ad) {
                            print('$ad onAdDismissedFullScreenContent.');
                            ad.dispose();
                          },
                          onAdFailedToShowFullScreenContent: (InterstitialAd ad, AdError error) {
                            print('$ad onAdFailedToShowFullScreenContent: $error');
                            ad.dispose();
                          },
                          onAdImpression: (InterstitialAd ad) {
                            interstitialAdload(); // <<<-------------- LOAD AD AGAIN WHEN THE USER WATCHES IT SO THAT ITS READY TO BE WATCHED JUST AFTER THE IMPRESSION OCCURS
                            print('$ad impression occurred.');
                          }
                        );
                      },
                      onAdFailedToLoad: (LoadAdError error) {
                        interstitialAdload(); // <<<-------------- LOAD AD AGAIN IF IT FAILS
                        print('InterstitialAd failed to load: $error');
                      },
                    ));
              }
            
              void rewardedAdLoad() {
                RewardedAd.load(
                    adUnitId: '<test ad>',
                    request: AdRequest(),
                rewardedAdLoadCallback: RewardedAdLoadCallback(
                onAdLoaded: (RewardedAd ad) {
                print('$ad loaded.');
                // Keep a reference to the ad so you can show it later.
                this._rewardedAd = ad;
                ad.fullScreenContentCallback = FullScreenContentCallback(
                  onAdShowedFullScreenContent: (RewardedAd ad) =>
                      print('$ad onAdShowedFullScreenContent.'),
                  onAdDismissedFullScreenContent: (RewardedAd ad) {
                    print('$ad onAdDismissedFullScreenContent.');
                    ad.dispose();
                  },
                  onAdFailedToShowFullScreenContent: (RewardedAd ad, AdError error) {
                    print('$ad onAdFailedToShowFullScreenContent: $error');
                    ad.dispose();
                  },
                  onAdImpression: (RewardedAd ad)
                  {
                    print('$ad impression occurred.');
                    rewardedAdLoad(); // <<<-------------- LOAD AD AGAIN WHEN THE USER WATCHES IT SO THAT ITS READY TO BE WATCHED JUST AFTER THE IMPRESSION OCCURS
                  }
                );
                },
                onAdFailedToLoad: (LoadAdError error) {
                  rewardedAdLoad(); // <<<-------------- LOAD AD AGAIN IF IT FAILS
                print('RewardedAd failed to load: $error');
                },
                )
                );
              }
            
              void showInterstitialAd() {
                _interstitialAd.show();
              }
           
            
              void showRewardedAd() {
                _rewardedAd.show(onUserEarnedReward: (RewardedAd ad, RewardItem rewardItem) {
                  // Reward the user for watching an ad.
                  reward();
                });
              }
        

        【讨论】:

        • 如果对您有帮助,请点赞并标记为正确,如果有任何疑问或错误,请告诉我。
        • 我相信它不会出现任何错误,因为我自己测试过并在我自己的应用程序中使用
        猜你喜欢
        • 2022-09-23
        • 2023-04-04
        • 2020-09-11
        • 2020-10-25
        • 2011-01-23
        • 2021-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多