AndriousSolutions / ads

Other
58 stars 11 forks source link

MobileAdListener fires events twice. #24

Closed jbenman closed 4 years ago

jbenman commented 4 years ago

I basically have the code from the example in an app, but whenever an ad event fires, the debugPrint statements in the switch statements print twice, and any code I call there gets called twice. Any idea what could be causing this?

Andrious commented 4 years ago

I haven't heard of such an issue. How about emailing me a sample of that bit of code?

support 'at' andrioussolutions.com

ricristian commented 4 years ago

Same issue here

I/flutter ( 3891): The ad is now open.
I/flutter ( 3891): An ad has been opened.
I/flutter ( 3891): You've just started playing the Video ad.
I/flutter ( 3891): You've just started playing the Video ad.
I/flutter ( 3891): You've just finished playing the Video ad.
I/flutter ( 3891): You've just finished playing the Video ad.
I/flutter ( 3891): The ad has sent a reward amount.
I/flutter ( 3891): The ad was sent a reward amount.
I/flutter ( 3891): You've closed the Ad and returned to the app.
I/flutter ( 3891): The video has been closed.
I/flutter ( 3891): An ad has loaded successfully in memory.
I/flutter ( 3891): An ad has loaded in memory.

code

import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:ads/ads.dart';
import 'package:firebase_admob/firebase_admob.dart';
import 'dart:io' show Platform;
import 'dart:convert' as convert;
import 'package:http/http.dart' as http;

class AdMob extends StatefulWidget {
  static String tag = 'friends';
  @override
  _AdMobState createState() => new _AdMobState();
}

class _AdMobState extends State<AdMob> {
  _AdMobState({this.initOption = 1});
  Ads _ads;

  List<dynamic> places = [];
  final Logger log = new Logger();

  Future _loadPlaces() async {
    try {
        // REST API CALL
  }

  final int initOption;
  int _coins = 0;

  final String appId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544~3347511713'
      : 'ca-app-pub-3940256099942544~1458002511';
  final String bannerUnitId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/6300978111'
      : 'ca-app-pub-3940256099942544/2934735716';
  final String screenUnitId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/1033173712'
      : 'ca-app-pub-3940256099942544/4411468910';
  final String videoUnitId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/5224354917'
      : 'ca-app-pub-3940256099942544/1712485313';

  @override
  void initState() {
    super.initState();
    _loadPlaces();

    switch (initOption) {
      case 1:

        /// Assign a listener.
        var eventListener = (MobileAdEvent event) {
          if (event == MobileAdEvent.clicked) {
            print("The opened ad is clicked on.");
          }
        };

        _ads = Ads(
          appId,
          bannerUnitId: bannerUnitId,
          screenUnitId: screenUnitId,
          videoUnitId: videoUnitId,
          keywords: <String>['ibm', 'computers'],
          contentUrl: 'http://www.ibm.com',
          childDirected: false,
          testDevices: ['Samsung_Galaxy_SII_API_26:5554'],
          testing: false,
          listener: eventListener,
        );

        break;

      case 2:
        _ads = Ads(appId);

        var videoListener = (RewardedVideoAdEvent event,
            {String rewardType, int rewardAmount}) {
          if (event == RewardedVideoAdEvent.rewarded) {
            print("The video ad has been rewarded.");
          }
        };

        _ads.setVideoAd(
          adUnitId: videoUnitId,
          keywords: ['dart', 'java'],
          contentUrl: 'http://www.publang.org',
          childDirected: true,
          testDevices: null,
          listener: videoListener,
        );

        break;

      case 3:
        _ads = Ads(appId);

        /// Assign the listener.
        var eventListener = (MobileAdEvent event) {
          if (event == MobileAdEvent.closed) {
            print("User has opened and now closed the ad.");
          }
        };

        /// You just show the Banner, Fullscreen and Video Ads separately.

        _ads.showBannerAd(
          adUnitId: bannerUnitId,
          size: AdSize.banner,
          keywords: ['andriod, flutter'],
          contentUrl: 'http://www.andrioussolutions.com',
          childDirected: false,
          testDevices: ['Samsung_Galaxy_SII_API_26:5554'],
          listener: eventListener,
        );

        _ads.showFullScreenAd(
            adUnitId: screenUnitId,
            keywords: ['dart', 'flutter'],
            contentUrl: 'http://www.fluttertogo.com',
            childDirected: false,
            testDevices: ['Samsung_Galaxy_SII_API_26:5554'],
            listener: (MobileAdEvent event) {
              if (event == MobileAdEvent.opened) {
                print("An ad has opened up.");
              }
            });

        var videoListener = (RewardedVideoAdEvent event,
            {String rewardType, int rewardAmount}) {
          if (event == RewardedVideoAdEvent.rewarded) {
            print("The video ad has been rewarded.");
          }
        };

        _ads.showVideoAd(
          adUnitId: videoUnitId,
          keywords: ['dart', 'java'],
          contentUrl: 'http://www.publang.org',
          childDirected: true,
          testDevices: null,
          listener: videoListener,
        );

        break;

      default:
        _ads = Ads(appId, testing: true);
    }

    _ads.videoListener =
        (RewardedVideoAdEvent event, {String rewardType, int rewardAmount}) {
      switch (event) {
        case RewardedVideoAdEvent.loaded:
          print("An ad has loaded successfully in memory.");
          break;
        case RewardedVideoAdEvent.failedToLoad:
          print("The ad failed to load into memory.");
          break;
        case RewardedVideoAdEvent.opened:
          print("The ad is now open.");
          break;
        case RewardedVideoAdEvent.leftApplication:
          print("You've left the app after clicking the Ad.");
          break;
        case RewardedVideoAdEvent.closed:
          print("You've closed the Ad and returned to the app.");
          break;
        case RewardedVideoAdEvent.rewarded:
          print("The ad has sent a reward amount.");
          break;
        case RewardedVideoAdEvent.started:
          print("You've just started playing the Video ad.");
          break;
        case RewardedVideoAdEvent.completed:
          print("You've just finished playing the Video ad.");
          break;
        default:
          print("There's a 'new' RewardedVideoAdEvent?!");
      }
    };

    VoidCallback handlerFunc = () {
      print("The opened ad was clicked on.");
    };

    _ads.video.loadedListener = () {
      print("An ad has loaded in memory.");
    };

    _ads.video.removeLoaded(handlerFunc);

    _ads.video.failedListener = () {
      print("An ad has failed to load in memory.");
    };

    _ads.video.removeFailed(handlerFunc);

    _ads.video.clickedListener = () {
      print("An ad has been clicked on.");
    };

    _ads.video.removeClicked(handlerFunc);

    _ads.video.openedListener = () {
      print("An ad has been opened.");
    };

    _ads.video.removeOpened(handlerFunc);

    _ads.video.leftAppListener = () {
      print("You've left the app to view the video.");
    };

    _ads.video.leftAppListener = handlerFunc;

    _ads.video.closedListener = () {
      print("The video has been closed.");
    };

    _ads.video.removeClosed(handlerFunc);

    _ads.video.rewardedListener = (String rewardType, int rewardAmount) {
      print("The ad was sent a reward amount.");
      setState(() {
        _coins += rewardAmount;
      });
    };

    RewardListener rewardHandler = (String rewardType, int rewardAmount) {
      print("This is the Rewarded Video handler");
    };

    _ads.video.removeRewarded(rewardHandler);

    _ads.video.startedListener = () {
      print("You've just started playing the Video ad.");
    };

    _ads.video.removeStarted(handlerFunc);

    _ads.video.completedListener = () {
      print("You've just finished playing the Video ad.");
    };

    _ads.video.removeCompleted(handlerFunc);

    // Uncomment and run this example
//    List<String> one = _ads.keywords;
//
//    String two = _ads.contentUrl;
//
//    bool three = _ads.childDirected;
//
//    List<String> four = _ads.testDevices;
//
//    bool five = _ads.initialized;
  }

  @override
  void dispose() {
    log.d(_ads);
    log.i("DIspoze ads");
    _ads.dispose();
    log.d(_ads);
    _ads = null;
    log.d(_ads);

    super.dispose();
  }

  bool myInterceptor(bool stopDefaultButtonEvent) {
    Navigator.of(context).pop();
    return true;
  }

  Widget build(BuildContext context) {
    // final deviceSize = MediaQuery.of(context).size;
    return Scaffold(
      backgroundColor: Colors.white,
      resizeToAvoidBottomPadding: false,
      body: Stack(children: <Widget>[
        Container(
          decoration: new BoxDecoration(
            image: DecorationImage(
              image: new AssetImage('assets/images/city_birds.jpg'),
              fit: BoxFit.fill,
            ),
          ),
        ),
        ListView.builder(
          itemCount: places.length,
          itemBuilder: (context, pos) {
            return Padding(
              padding: EdgeInsets.only(bottom: 16.0),
              child: Card(
                color: Colors.white,
                child: InkWell(
                  onTap: () => {_ads.showVideoAd(state: this)},
                  child: Padding(
                    padding:
                        EdgeInsets.symmetric(vertical: 24.0, horizontal: 16.0),
                    child: Text(
                      places[pos]["desc"],
                      style: TextStyle(
                        fontSize: 18.0,
                        height: 1.6,
                      ),
                    ),
                  ),
                ),
              ),
            );
          },
        ),
        SingleChildScrollView(
          child: Container(
            // height: deviceSize.height,
            // width: deviceSize.width,
            child: Column(
              // mainAxisAlignment: MainAxisAlignment.center,
              // crossAxisAlignment: CrossAxisAlignment.center,
              // crossAxisAlignment: CrossAxisAlignment.center,
              // mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                // flex: deviceSize.width > 600 ? 2 : 1,

                // RaisedButton(
                //     key: ValueKey<String>('SHOW BANNER'),
                //     child: const Text('SHOW BANNER'),
                //     onPressed: () {
                //       _ads.showBannerAd(state: this, anchorOffset: null);
                //     }),
                // RaisedButton(
                //     key: ValueKey<String>('REMOVE BANNER'),
                //     child: const Text('REMOVE BANNER'),
                //     onPressed: () {
                //       _ads.closeBannerAd();
                //     }),
                // RaisedButton(
                //   key: ValueKey<String>('SHOW INTERSTITIAL'),
                //   child: const Text('SHOW INTERSTITIAL'),
                //   onPressed: () {
                //     _ads.showFullScreenAd(state: this);
                //   },
                // ),
                // RaisedButton(
                //   key: ValueKey<String>('SHOW REWARDED VIDEO'),
                //   child: const Text('SHOW REWARDED VIDEO'),
                //   onPressed: () {
                //     _ads.showVideoAd(state: this);
                //   },
                // ),
                Text(
                  "You have $_coins coins.",
                  key: ValueKey<String>('COINS'),
                ),
              ].map((Widget button) {
                return Padding(
                  padding: const EdgeInsets.symmetric(vertical: 6.0),
                  child: button,
                );
              }).toList(),
            ),
          ),
        ),
      ]),
    );
  }
}
Andrious commented 4 years ago

MobileAdListener is not firing events twice. Two listeners are firing in turn. Below the messages have been modified indicating the listener the message originates from. It's two separate listeners firing and providing messages. Like any good library package, there should always be more that one way to 'skin a cat.' Or in this case, to set an event listener. Two are set in the code.

I/flutter ( 3891): _ads.videoListener: The ad is now open.
I/flutter ( 3891): _ads.video.openedListener: An ad has been opened.
I/flutter ( 3891): _ads.videoListener: You've just started playing the Video ad.
I/flutter ( 3891): _ads.video.startedListener: You've just started playing the Video ad.
I/flutter ( 3891): _ads.videoListener: You've just finished playing the Video ad.
I/flutter ( 3891): _ads.video.completedListener: You've just finished playing the Video ad.
I/flutter ( 3891): _ads.videoListener: The ad has sent a reward amount.
I/flutter ( 3891): _ads.video.rewardedListener: The ad was sent a reward amount.
I/flutter ( 3891): _ads.videoListener: You've closed the Ad and returned to the app.
I/flutter ( 3891): _ads.video.closedListener: The video has been closed.
I/flutter ( 3891): _ads.videoListener: An ad has loaded successfully in memory.
I/flutter ( 3891): _ads.video.loadedListener: An ad has loaded in memory.

The original code you supplied me above has been modified below to convey these messages. There is a section in the article, Add Ads To Your App In A Snap!, that describes the event listeners available to you. However, maybe go to the section described in the Github for this package under, Listen and Earn!, first as it's more concise.

import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:ads/ads.dart';
import 'package:firebase_admob/firebase_admob.dart';
import 'dart:io' show Platform;
//import 'dart:convert' as convert;
//import 'package:http/http.dart' as http;

class AdMob extends StatefulWidget {
  static String tag = 'friends';
  @override
  _AdMobState createState() => new _AdMobState();
}

class _AdMobState extends State<AdMob> {
  _AdMobState({this.initOption = 1});

  Ads _ads;

  List<dynamic> places = [];
  final Logger log = new Logger();

//  Future _loadPlaces() async {
//    try {
//      // REST API CALL
//    }

    final int initOption;
    int _coins = 0;

    final String appId = Platform.isAndroid
        ? 'ca-app-pub-3940256099942544~3347511713'
        : 'ca-app-pub-3940256099942544~1458002511';
    final String bannerUnitId = Platform.isAndroid
        ? 'ca-app-pub-3940256099942544/6300978111'
        : 'ca-app-pub-3940256099942544/2934735716';
    final String screenUnitId = Platform.isAndroid
        ? 'ca-app-pub-3940256099942544/1033173712'
        : 'ca-app-pub-3940256099942544/4411468910';
    final String videoUnitId = Platform.isAndroid
        ? 'ca-app-pub-3940256099942544/5224354917'
        : 'ca-app-pub-3940256099942544/1712485313';

    @override
    void initState() {
      super.initState();
//      _loadPlaces();

      switch (initOption) {
        case 1:

        /// Assign a listener.
          var eventListener = (MobileAdEvent event) {
            if (event == MobileAdEvent.clicked) {
              print("The opened ad is clicked on.");
            }
          };

          _ads = Ads(
            appId,
            bannerUnitId: bannerUnitId,
            screenUnitId: screenUnitId,
            videoUnitId: videoUnitId,
            keywords: <String>['ibm', 'computers'],
            contentUrl: 'http://www.ibm.com',
            childDirected: false,
            testDevices: ['Samsung_Galaxy_SII_API_26:5554'],
            testing: false,
            listener: eventListener,
          );

          break;

        case 2:
          _ads = Ads(appId);

          var videoListener = (RewardedVideoAdEvent event,
              {String rewardType, int rewardAmount}) {
            if (event == RewardedVideoAdEvent.rewarded) {
              print("The video ad has been rewarded.");
            }
          };

          _ads.setVideoAd(
            adUnitId: videoUnitId,
            keywords: ['dart', 'java'],
            contentUrl: 'http://www.publang.org',
            childDirected: true,
            testDevices: null,
            listener: videoListener,
          );

          break;

        case 3:
          _ads = Ads(appId);

          /// Assign the listener.
          var eventListener = (MobileAdEvent event) {
            if (event == MobileAdEvent.closed) {
              print("User has opened and now closed the ad.");
            }
          };

          /// You just show the Banner, Fullscreen and Video Ads separately.

          _ads.showBannerAd(
            adUnitId: bannerUnitId,
            size: AdSize.banner,
            keywords: ['andriod, flutter'],
            contentUrl: 'http://www.andrioussolutions.com',
            childDirected: false,
            testDevices: ['Samsung_Galaxy_SII_API_26:5554'],
            listener: eventListener,
          );

          _ads.showFullScreenAd(
              adUnitId: screenUnitId,
              keywords: ['dart', 'flutter'],
              contentUrl: 'http://www.fluttertogo.com',
              childDirected: false,
              testDevices: ['Samsung_Galaxy_SII_API_26:5554'],
              listener: (MobileAdEvent event) {
                if (event == MobileAdEvent.opened) {
                  print("An ad has opened up.");
                }
              });

          var videoListener = (RewardedVideoAdEvent event,
              {String rewardType, int rewardAmount}) {
            if (event == RewardedVideoAdEvent.rewarded) {
              print("The video ad has been rewarded.");
            }
          };

          _ads.showVideoAd(
            adUnitId: videoUnitId,
            keywords: ['dart', 'java'],
            contentUrl: 'http://www.publang.org',
            childDirected: true,
            testDevices: null,
            listener: videoListener,
          );

          break;

        default:
          _ads = Ads(appId, testing: true);
      }

      _ads.videoListener =
          (RewardedVideoAdEvent event, {String rewardType, int rewardAmount}) {
        switch (event) {
          case RewardedVideoAdEvent.loaded:
            print("_ads.videoListener: An ad has loaded successfully in memory.");
            break;
          case RewardedVideoAdEvent.failedToLoad:
            print("_ads.videoListener: The ad failed to load into memory.");
            break;
          case RewardedVideoAdEvent.opened:
            print("_ads.videoListener:  The ad is now open");
            break;
          case RewardedVideoAdEvent.leftApplication:
            print("_ads.videoListener: You've gone to the Ad itself.");
            break;
          case RewardedVideoAdEvent.closed:
            print("_ads.videoListener: You've closed the Ad and returned to the app.");
            break;
          case RewardedVideoAdEvent.rewarded:
            print("_ads.videoListener: The ad has sent a reward amount.");
            break;
          case RewardedVideoAdEvent.started:
            print("_ads.videoListener: You've just started playing the Video ad.");
            break;
          case RewardedVideoAdEvent.completed:
            print("_ads.videoListener: You've just finished playing the Video ad.");
            break;
          default:
            print("_ads.videoListener: There's a 'new' RewardedVideoAdEvent?!");
        }
      };

      VoidCallback handlerFunc = () {
        print("handlerFunc: The opened ad was clicked on.");
      };

      _ads.video.loadedListener = () {
        print("_ads.video.loadedListener: An ad has loaded in memory.");
      };

      _ads.video.removeLoaded(handlerFunc);

      _ads.video.failedListener = () {
        print(" _ads.video.failedListener: An ad has failed to load in memory.");
      };

      _ads.video.removeFailed(handlerFunc);

      _ads.video.clickedListener = () {
        print("_ads.video.clickedListener: An ad has been clicked on.");
      };

      _ads.video.removeClicked(handlerFunc);

      _ads.video.openedListener = () {
        print("_ads.video.openedListener: An ad has been opened.");
      };

      _ads.video.removeOpened(handlerFunc);

      _ads.video.leftAppListener = () {
        print("_ads.video.leftAppListener: You've left the app to view the video.");
      };

      _ads.video.leftAppListener = handlerFunc;

      _ads.video.closedListener = () {
        print("_ads.video.closedListener: The video has been closed.");
      };

      _ads.video.removeClosed(handlerFunc);

      _ads.video.rewardedListener = (String rewardType, int rewardAmount) {
        print("_ads.video.rewardedListener: The ad was sent a reward amount.");
        setState(() {
          _coins += rewardAmount;
        });
      };

      RewardListener rewardHandler = (String rewardType, int rewardAmount) {
        print("rewardHandler: This is the Rewarded Video handler");
      };

      _ads.video.removeRewarded(rewardHandler);

      _ads.video.startedListener = () {
        print("_ads.video.startedListener: You've just started playing the Video ad.");
      };

      _ads.video.removeStarted(handlerFunc);

      _ads.video.completedListener = () {
        print("_ads.video.completedListener: You've just finished playing the Video ad.");
      };

      _ads.video.removeCompleted(handlerFunc);

      // Uncomment and run this example
//    List<String> one = _ads.keywords;
//
//    String two = _ads.contentUrl;
//
//    bool three = _ads.childDirected;
//
//    List<String> four = _ads.testDevices;
//
//    bool five = _ads.initialized;
    }

    @override
    void dispose() {
      log.d(_ads);
      log.i("DIspoze ads");
      _ads.dispose();
      log.d(_ads);
      _ads = null;
      log.d(_ads);

      super.dispose();
    }

    bool myInterceptor(bool stopDefaultButtonEvent) {
      Navigator.of(context).pop();
      return true;
    }

    Widget build(BuildContext context) {
      // final deviceSize = MediaQuery.of(context).size;
      return Scaffold(
        backgroundColor: Colors.white,
        resizeToAvoidBottomPadding: false,
        body: Stack(children: <Widget>[
          Container(
            decoration: new BoxDecoration(
              image: DecorationImage(
                image: new AssetImage('assets/images/city_birds.jpg'),
                fit: BoxFit.fill,
              ),
            ),
          ),
          ListView.builder(
            itemCount: places.length,
            itemBuilder: (context, pos) {
              return Padding(
                padding: EdgeInsets.only(bottom: 16.0),
                child: Card(
                  color: Colors.white,
                  child: InkWell(
                    onTap: () => {_ads.showVideoAd(state: this)},
                    child: Padding(
                      padding:
                      EdgeInsets.symmetric(vertical: 24.0, horizontal: 16.0),
                      child: Text(
                        places[pos]["desc"],
                        style: TextStyle(
                          fontSize: 18.0,
                          height: 1.6,
                        ),
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
          SingleChildScrollView(
            child: Container(
              // height: deviceSize.height,
              // width: deviceSize.width,
              child: Column(
                // mainAxisAlignment: MainAxisAlignment.center,
                // crossAxisAlignment: CrossAxisAlignment.center,
                // crossAxisAlignment: CrossAxisAlignment.center,
                // mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  // flex: deviceSize.width > 600 ? 2 : 1,

                  // RaisedButton(
                  //     key: ValueKey<String>('SHOW BANNER'),
                  //     child: const Text('SHOW BANNER'),
                  //     onPressed: () {
                  //       _ads.showBannerAd(state: this, anchorOffset: null);
                  //     }),
                  // RaisedButton(
                  //     key: ValueKey<String>('REMOVE BANNER'),
                  //     child: const Text('REMOVE BANNER'),
                  //     onPressed: () {
                  //       _ads.closeBannerAd();
                  //     }),
                  // RaisedButton(
                  //   key: ValueKey<String>('SHOW INTERSTITIAL'),
                  //   child: const Text('SHOW INTERSTITIAL'),
                  //   onPressed: () {
                  //     _ads.showFullScreenAd(state: this);
                  //   },
                  // ),
                  // RaisedButton(
                  //   key: ValueKey<String>('SHOW REWARDED VIDEO'),
                  //   child: const Text('SHOW REWARDED VIDEO'),
                  //   onPressed: () {
                  //     _ads.showVideoAd(state: this);
                  //   },
                  // ),
                  Text(
                    "You have $_coins coins.",
                    key: ValueKey<String>('COINS'),
                  ),
                ].map((Widget button) {
                  return Padding(
                    padding: const EdgeInsets.symmetric(vertical: 6.0),
                    child: button,
                  );
                }).toList(),
              ),
            ),
          ),
        ]),
      );
    }
  }