Flutter集成激励广告遇加载失败错误,需实现观看后加分功能
问题解决:Flutter激励广告加载失败(错误码3)+ 积分奖励实现
一、错误码3(ERROR_CODE_NO_FILL)的排查与解决
错误码3表示无广告填充,结合日志和代码,从以下几点修复:
- 初始化MobileAds服务
必须在APP启动时完成AdMob初始化,否则广告加载会异常。在main()函数中添加:
import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:flutter/material.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await MobileAds.instance.initialize(); runApp(const MyApp()); }
- 使用AdMob测试广告单元ID
正式广告单元ID在测试阶段大概率无法获取填充,替换为官方测试ID:
- Android:
ca-app-pub-3940256099942544/5224354917 - iOS:
ca-app-pub-3940256099942544/1712485313
测试阶段用上述ID验证,上线后替换为你的正式ID。
更新设备Google Play服务
日志中出现Dynamic lookup for intent failed,说明设备Google Play服务版本过低,更新后重试。完善错误日志打印
在onAdFailedToLoad中打印错误详情,便于精准排查:
onAdFailedToLoad: (error) { print('激励广告加载失败: ${error.message}'); setState(() => _rewardedAd = null); // 可选:延迟3秒重试加载 Future.delayed(const Duration(seconds: 3), () => _createRewardedAd()); }
二、积分奖励功能优化
当前代码仅实现基础积分递增,可从以下几点完善:
- 根据广告奖励值动态增加积分
广告奖励可能有不同额度,使用reward.amount而非固定+1:
_rewardedAd!.show(onUserEarnedReward: (ad, reward) { setState(() => _rewardedScore += reward.amount.toInt()); // 持久化积分,避免重启丢失 _saveScore(); });
- 积分持久化(避免重启丢失)
使用shared_preferences存储积分,先在pubspec.yaml添加依赖:
dependencies: shared_preferences: ^2.2.2
然后实现读取和保存逻辑:
import 'package:shared_preferences/shared_preferences.dart'; // 初始化时读取本地积分 @override void initState() { super.initState(); _loadScore(); _createRewardedAd(); } Future<void> _loadScore() async { final prefs = await SharedPreferences.getInstance(); setState(() => _rewardedScore = prefs.getInt('rewarded_score') ?? 0); } Future<void> _saveScore() async { final prefs = await SharedPreferences.getInstance(); await prefs.setInt('rewarded_score', _rewardedScore); }
- 广告生命周期安全管理
优化逻辑避免空指针异常:
void _showRewardedAd() { final ad = _rewardedAd; if (ad == null) { print('广告未加载完成,请稍后重试'); return; } ad.fullScreenContentCallback = FullScreenContentCallback( onAdDismissedFullScreenContent: (ad) { ad.dispose(); _createRewardedAd(); }, onAdFailedToShowFullScreenContent: (ad, error) { print('广告展示失败: ${error.message}'); ad.dispose(); _createRewardedAd(); }, ); ad.show(onUserEarnedReward: (ad, reward) { setState(() => _rewardedScore += reward.amount.toInt()); _saveScore(); }); _rewardedAd = null; }
三、完整修正代码
import 'package:flutter/material.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:shared_preferences/shared_preferences.dart'; class Purchase extends StatefulWidget { const Purchase({Key? key}) : super(key: key); @override State<Purchase> createState() => _PurchaseState(); } class _PurchaseState extends State<Purchase> { RewardedAd? _rewardedAd; int _rewardedScore = 0; // 测试广告单元ID(根据平台自动适配) final String _testRewardedAdUnitId = MobileAds.instance.isAndroid ? 'ca-app-pub-3940256099942544/5224354917' : 'ca-app-pub-3940256099942544/1712485313'; void _createRewardedAd() { RewardedAd.load( adUnitId: _testRewardedAdUnitId, request: const AdRequest(), rewardedAdLoadCallback: RewardedAdLoadCallback( onAdLoaded: (ad) { print('激励广告加载成功'); setState(() => _rewardedAd = ad); }, onAdFailedToLoad: (error) { print('激励广告加载失败: ${error.message}'); setState(() => _rewardedAd = null); Future.delayed(const Duration(seconds: 3), () => _createRewardedAd()); }, ), ); } void _showRewardedAd() { final ad = _rewardedAd; if (ad == null) { print('广告未加载完成,请稍后重试'); return; } ad.fullScreenContentCallback = FullScreenContentCallback( onAdDismissedFullScreenContent: (ad) { ad.dispose(); _createRewardedAd(); }, onAdFailedToShowFullScreenContent: (ad, error) { print('广告展示失败: ${error.message}'); ad.dispose(); _createRewardedAd(); }, ); ad.show(onUserEarnedReward: (ad, reward) { setState(() => _rewardedScore += reward.amount.toInt()); _saveScore(); print('用户获得${reward.amount}积分'); }); _rewardedAd = null; } Future<void> _loadScore() async { final prefs = await SharedPreferences.getInstance(); setState(() => _rewardedScore = prefs.getInt('rewarded_score') ?? 0); } Future<void> _saveScore() async { final prefs = await SharedPreferences.getInstance(); await prefs.setInt('rewarded_score', _rewardedScore); } @override void initState() { super.initState(); _loadScore(); _createRewardedAd(); } @override void dispose() { _rewardedAd?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Container( alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('当前积分: $_rewardedScore', style: const TextStyle(color: Colors.white, fontSize: 20)), const SizedBox(height: 30), ElevatedButton( onPressed: _showRewardedAd, child: const Text('观看广告赚积分'), ), ], ), ), ); } }
内容的提问来源于stack exchange,提问作者Faizan Abbas
相关产品推荐
相关产品推荐

