You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用google_mobile_ads如何仅给看完完整视频广告的用户发放奖励

激励广告跳过仍发放奖励问题修复方案

问题原因

你当前使用的google_mobile_ads: ^0.13.5版本中,onUserEarnedReward回调本身是谷歌官方控制的,只有用户完整观看广告满足发奖条件时才会触发,跳过广告时该回调不会执行。你遇到跳过仍发奖的问题,基本是因为实际业务的发奖逻辑没有绑定到onUserEarnedReward回调,而是写到了只要关闭广告就会触发的onAdDismissedFullScreenContent回调里,或者你传入的onEnd参数没有和发奖资格绑定。

修复步骤

  1. 新增标识位判断用户是否完成广告观看
  2. 所有发奖逻辑统一放到onUserEarnedReward回调中执行
  3. 广告关闭时通过标识位判断是否需要执行后续非发奖类的收尾逻辑

修改后代码示例

class AdsBloc extends ChangeNotifier{

  int _rewardedPoint = 0 ;
  // 新增标识位:判断用户是否完成广告观看满足发奖条件
  bool _hasEarnedReward = false;

  int getrewardpoint() => _rewardedPoint;

  RewardedAd _rewardedAd;
  int _numRewardedLoadAttempts = 0;

  static initialization(){
    if(MobileAds.instance == null)
    {
      MobileAds.instance.initialize();
    }
  }

  void createRewardedAd() {
    RewardedAd.load(
        adUnitId: Config().admobRewardAdId,
        request: AdRequest(),
        rewardedAdLoadCallback: RewardedAdLoadCallback(
          onAdLoaded: (RewardedAd ad) {
            print('$ad loaded.');
            _rewardedAd = ad;
            _numRewardedLoadAttempts = 0;
          },
          onAdFailedToLoad: (LoadAdError error) {
            print('RewardedAd failed to load: $error');
            _rewardedAd = null;
            _numRewardedLoadAttempts += 1;
            if (_numRewardedLoadAttempts <= 2) {
              createRewardedAd();
            }
          },
        ));
  }

  void showRewardedAd(Future<dynamic> onEnd) {
    if (_rewardedAd == null) {
      print('Warning: attempt to show rewarded before loaded.');
      return;
    }
    // 每次展示广告前重置标识位
    _hasEarnedReward = false;
    
    _rewardedAd.fullScreenContentCallback = FullScreenContentCallback(
      onAdShowedFullScreenContent: (RewardedAd ad) =>
          print('ad onAdShowedFullScreenContent.'),
      onAdDismissedFullScreenContent: (RewardedAd ad) {
        print('$ad onAdDismissedFullScreenContent.User dismissed');
        ad.dispose();
        createRewardedAd();
        // 这里只有完成观看的用户才执行onEnd,如果不管完不完成都要执行就去掉if判断
        if(_hasEarnedReward){
          onEnd();
        }
      },
      onAdWillDismissFullScreenContent: (ad) {
        print("pleasee dont");
      },
      onAdFailedToShowFullScreenContent: (RewardedAd ad, AdError error) {
        print('$ad onAdFailedToShowFullScreenContent: $error');
        ad.dispose();
        createRewardedAd();
      },
      onAdImpression: (RewardedAd ad) => print('$ad impression occurred.'),
    );
    _rewardedAd.setImmersiveMode(true);
    _rewardedAd.show(onUserEarnedReward: (RewardedAd ad, RewardItem reward) {
      // 标记用户完成观看
      _hasEarnedReward = true;
      // 所有发奖逻辑统一在这里执行
      _rewardedPoint += reward.amount;
      print("ad watched give them reward");
      // 你的其他发奖业务逻辑写在这里
      
      print('$ad with reward $RewardItem(${reward.amount}, ${reward.type}');
    });
    _rewardedAd = null;
  }

}

注意事项

  • 不要在onAdDismissedFullScreenContent回调中执行任何发奖相关逻辑,该回调只要用户关闭广告就会触发,不管是否跳过广告
  • 你原有代码中的_preReward判断逻辑没有实际作用,只要进入onUserEarnedReward回调就说明用户已经满足发奖条件,可以直接执行发奖逻辑

内容的提问来源于stack exchange,提问作者ARUN BALAJI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:06:03