import 'dart:io' show Platform; import 'package:flutter/material.dart'; import 'package:unity_levelplay_mediation/unity_levelplay_mediation.dart'; import '../screens/main_screen.dart'; import 'app_ads_managers.dart'; /// Loading 页面 - 显示 logo 和 loading 动画,初始化广告 class StartPage extends StatefulWidget { final Widget Function()? homePageBuilder; const StartPage({super.key, this.homePageBuilder}); @override State createState() => _StartPageState(); } class _StartPageState extends State with WidgetsBindingObserver { final InterstitialAdManager _adManager = InterstitialAdManager(); bool _hasRequestedATT = false; bool _isInitializing = false; bool _isWaitingForATT = false; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); _initializeAds(); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); // 当应用从后台回到前台时,如果还没有请求过ATT,则请求 if (state == AppLifecycleState.resumed && !_hasRequestedATT && Platform.isIOS && !_isInitializing) { _requestATTWhenReady(); } } Future _initializeAds() async { _isInitializing = true; try { // iOS 平台:智能等待并请求 ATT 权限 if (Platform.isIOS) { await _requestATTWhenReady(); } // ATT 请求完成后,初始化广告管理器 _adManager.initialize(); // 等待初始化完成 await _waitForInitialization(); if (mounted) { // 并行加载三个广告,任意一个成功就立即跳转并显示 _adManager.loadInitialSplashAd( onAdReady: (adType) { if (mounted) { // 延迟一小段时间后跳转并显示广告 Future.delayed(const Duration(milliseconds: 500)).then((_) { if (mounted) { _navigateToHomeAndShowAd(adType); } }); } }, onAllAdsFailed: () { if (mounted) { // 所有广告都失败,延迟后进入主页 Future.delayed(const Duration(seconds: 1)).then((_) { if (mounted) { _navigateToHome(); } }); } }, ); } } catch (e) { if (mounted) { // 即使初始化失败,也允许进入主页(广告可能稍后可用) await Future.delayed(const Duration(seconds: 2)); if (mounted) { _navigateToHome(); } } } finally { _isInitializing = false; } } /// 导航到主页并显示广告 void _navigateToHomeAndShowAd(InterstitialAdType adType) { // 对于开屏场景,直接跳到 HomePage,并把已准备好的广告类型传过去 Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (context) => MainScreen(initialSplashAdType: adType), ), ); } /// 导航到主页 void _navigateToHome() { if (widget.homePageBuilder != null) { Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (context) => widget.homePageBuilder!()), ); } } /// 智能等待并请求 ATT 权限,确保没有其他权限对话框在显示 Future _requestATTWhenReady() async { if (_hasRequestedATT || _isWaitingForATT) return; _isWaitingForATT = true; try { // 检查当前ATT状态 final currentStatus = await ATTrackingManager.getTrackingAuthorizationStatus(); debugPrint('LoadingPage: ATT Status: $currentStatus'); if (currentStatus != ATTStatus.NotDetermined) { _hasRequestedATT = true; _isWaitingForATT = false; return; } // 初始延迟,让系统处理其他权限 await Future.delayed(const Duration(milliseconds: 2000)); // 智能等待:检测是否有其他系统对话框 await _waitForSystemDialogsToClear(); // 最终检查:确保状态仍然是 NotDetermined final finalStatus = await ATTrackingManager.getTrackingAuthorizationStatus(); if (finalStatus == ATTStatus.NotDetermined && mounted) { _hasRequestedATT = true; debugPrint('LoadingPage: Requesting ATT permission...'); final returnedStatus = await ATTrackingManager.requestTrackingAuthorization(); debugPrint('LoadingPage: ATT Status returned: $returnedStatus'); } else { _hasRequestedATT = true; } } catch (e) { debugPrint('LoadingPage: ATT request error: $e'); _hasRequestedATT = true; } finally { _isWaitingForATT = false; } } /// 等待系统对话框清除 /// 通过监听应用生命周期状态变化来检测是否有系统对话框 Future _waitForSystemDialogsToClear() async { const maxWaitTime = Duration(seconds: 30); // 最多等待30秒 const checkInterval = Duration(milliseconds: 500); final startTime = DateTime.now(); AppLifecycleState? lastState = WidgetsBinding.instance.lifecycleState; int stableCount = 0; const requiredStableCount = 4; // 需要连续2秒保持稳定状态 while (DateTime.now().difference(startTime) < maxWaitTime) { if (!mounted) break; await Future.delayed(checkInterval); final currentState = WidgetsBinding.instance.lifecycleState; // 如果应用状态稳定在 resumed,说明没有系统对话框 if (currentState == AppLifecycleState.resumed) { if (lastState == AppLifecycleState.resumed) { stableCount++; if (stableCount >= requiredStableCount) { debugPrint('LoadingPage: App state stable, ready for ATT request'); break; } } else { stableCount = 1; } } else { // 如果状态不是 resumed,重置计数 stableCount = 0; debugPrint('LoadingPage: App state: $currentState, waiting...'); } lastState = currentState; } // 额外的安全延迟 await Future.delayed(const Duration(milliseconds: 1000)); } /// 等待广告管理器初始化完成 Future _waitForInitialization() async { // 轮询检查初始化状态,最多等待 15 秒 const maxWaitTime = Duration(seconds: 15); const checkInterval = Duration(milliseconds: 200); final startTime = DateTime.now(); while (DateTime.now().difference(startTime) < maxWaitTime) { if (_adManager.isInitialized) { return; } await Future.delayed(checkInterval); } // 如果超时仍未初始化,记录警告但继续 if (!_adManager.isInitialized) { debugPrint('Warning: Ad initialization timeout, proceeding anyway'); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color(0xff141420), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Logo with animation TweenAnimationBuilder( tween: Tween(begin: 0.0, end: 1.0), duration: const Duration(milliseconds: 800), curve: Curves.easeOut, builder: (context, value, child) { return Opacity( opacity: value, child: Transform.scale(scale: value, child: child), ); }, child: Image.asset( 'assets/images/stonicons.png', width: 100, height: 100, fit: BoxFit.contain, ), ), const SizedBox(height: 5), // 状态文本 const Text( 'Resource Loading', style: TextStyle( fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 5), // Loading 动画 const SizedBox( width: 30, height: 30, child: CircularProgressIndicator( strokeWidth: 4, valueColor: AlwaysStoppedAnimation(Color(0xFFFFFFFF)), ), ), const SizedBox(height: 30), ], ), ), ); } }