adwhale_sdk_flutter 2.7.2+0
adwhale_sdk_flutter: ^2.7.2+0 copied to clipboard
Adwhale SDK Flutter plugin for integrating Adwhale advertising mediation SDK into Flutter applications.
example/lib/main.dart
import 'dart:developer';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:adwhale_sdk_flutter/adwhale_sdk_flutter.dart';
import 'native_test_page.dart';
import 'foreground_test_page.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
AdWhaleMediationAds.instance.initialize();
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
final GlobalKey<ScaffoldMessengerState> _scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
BannerAd? _banner;
InterstitialAd? _interstitialAd;
RewardAd? _rewardAd;
AppOpenAd? _appOpenAd;
@override
void initState() {
super.initState();
// 앱 시작 시 AppOpen 광고 자동 요청/표시
_createAppOpenAd();
}
/// 전달받은 enum 사이즈로 BannerAd를 생성 및 로드
void _createBanner(BannerHeightEnum bannerSize) {
print('FlutterCreating BannerAd with enum $bannerSize');
_banner = BannerAd(
listener: BannerAdListener(
onReceiveAd: (ad) {
print('FlutterBannerAd onReceiveAd for size $bannerSize received');
setState(() {}); // 광고 로드 성공 시 UI 갱신
},
onFailedToReceiveAd: (ad, errorCode, errorMessage) {
print('BannerAd onFailedToReceiveAd for $bannerSize: errorCode: $errorCode, errorMessage: $errorMessage');
ad.dispose();
setState(() {
_banner = null;
});
},
onCloseLandingScreen: (ad) {
print('FlutterBannerAd onCloseLandingScreen for size $bannerSize');
},
onShowLandingScreen: (ad) {
print('FlutterBannerAd onShowLandingScreen for size $bannerSize');
},
),
// AdInfo에 enum만 전달합니다.
adInfo: AdInfo("PlacementUid를 입력 하세요.", bannerSize),
)..load();
print('FlutterBannerAd load() called for $bannerSize');
}
/// 기존 배너를 제거한 후, 지정한 enum 사이즈의 새 배너 광고를 호출합니다.
void _showBannerAd(BannerHeightEnum bannerSize) {
print('FlutterBannerAd _showBannerAd() called for $bannerSize');
if (_banner != null) {
print('FlutterDisposing existing banner');
_banner!.dispose();
_banner = null;
}
setState(() {}); // UI에 기존 배너 제거 반영
_createBanner(bannerSize);
}
void _createReward() {
print('FlutterRewardAd _createReward()');
_rewardAd = RewardAd(
appCode: "PlacementUid를 입력 하세요.",
adRewardLoadCallback: RewardAdLoadCallback(
onRewardAdLoaded: () {
print('FlutterRewardAd onAdLoaded');
_rewardAd!.show();
},
onRewardAdFailedToLoad: (errorCode, errorMessage) {
print('FlutterRewardAd onAdFailedToLoad: errorCode: $errorCode, errorMessage: $errorMessage');
_rewardAd = null;
},
onUserRewarded: (amount, type) {
print('FlutterRewardAd onUserRewarded');
print('FlutterRewardAd onUserRewarded: amount: $amount, type: $type');
},
onRewardAdClicked: () {
print('FlutterRewardAd onAdClicked');
},
onRewardAdShowed: () {
print('FlutterRewardAd onAdShowed');
_rewardAd = null;
},
onRewardFailedToShow: (String errorCode, String errorMessage) {
print('FlutterRewardAd onFailedToShow: errorCode: $errorCode, errorMessage: $errorMessage');
},
onRewardAdDismissed: () {
print('FlutterRewardAd onDismissed');
},
),
);
_rewardAd!.load();
}
void _createInterstitialAd() {
print('FlutterInterstitialAd _createInterstitialAd()');
_interstitialAd = InterstitialAd(
appCode: "PlacementUid를 입력 하세요.",
adLoadCallback: InterstitialAdLoadCallback(
onInterstitialAdLoaded: () {
print('FlutterInterstitialAd onAdLoaded');
_interstitialAd!.show();
},
onInterstitialAdLoadFailed: (errorCode, errorMessage) {
print('FlutterInterstitialAd onAdLoadFailed: $errorMessage');
_interstitialAd = null;
},
onInterstitialAdShowed: () {
print('FlutterInterstitialAd onAdShowed');
},
onInterstitialAdShowFailed: (errorCode, errorMessage) {
print('FlutterInterstitialAd onAdShowFailed: $errorMessage');
_interstitialAd = null;
},
onInterstitialAdClosed: () {
print('FlutterInterstitialAd onAdClosed');
},
onInterstitialAdClicked: () {
print('FlutterInterstitialAd onAdClicked');
},
),
);
_interstitialAd?.load();
}
void _showRewardedAd() {
print('FlutterRewardAd _showRewardedAd()');
_createReward();
}
void _showInterstitialAd() {
print('FlutterInterstitialAd _showInterstitialAd()');
_createInterstitialAd();
}
// 앱오프닝 생성 및 호출
void _createAppOpenAd() {
print('FlutterAppOpenAd _createAppOpenAd()');
_appOpenAd = AppOpenAd(
placementUid: "PlacementUid를 입력 하세요.", // TODO: 실제 발급 UID로 교체
region: "서울시 강남구",
gcoderX: 37.5665,
gcoderY: 126.9780,
placementName: "test_app_open",
debugEnabled: true,
adLoadCallback: AppOpenAdLoadCallback(
onAppOpenAdLoaded: () {
print('FlutterAppOpenAd onAdLoaded');
_appOpenAd?.show();
},
onAppOpenAdLoadFailed: (code, message) {
print('FlutterAppOpenAd onAdLoadFailed: $code, $message');
_appOpenAd = null;
},
onAppOpenAdShowed: () {
print('FlutterAppOpenAd onAdShowed');
},
onAppOpenAdShowFailed: (code, message) {
print('FlutterAppOpenAd onAdShowFailed: $code, $message');
_appOpenAd = null;
},
onAppOpenAdDismissed: () {
print('FlutterAppOpenAd onAdDismissed');
},
onAppOpenAdClicked: () {
print('FlutterAppOpenAd onAdClicked');
},
),
);
_appOpenAd!.load();
}
Future<void> _requestGdpr() async {
final res = await AdWhaleMediationAds.instance.requestGdprConsent();
final ok = res['success'] == true;
final msg = (res['message'] ?? '').toString();
_scaffoldMessengerKey.currentState?.showSnackBar(
SnackBar(content: Text('GDPR호출: ${ok ? '성공' : '실패'} ${msg.isNotEmpty ? '($msg)' : ''}')),
);
}
Future<void> _resetGdpr() async {
await AdWhaleMediationAds.instance.resetGdprConsentStatus();
_scaffoldMessengerKey.currentState?.showSnackBar(
const SnackBar(content: Text('GDPR 상태 리셋 완료')),
);
}
Future<void> _setGdprFixed(bool hasConsent) async {
await AdWhaleMediationAds.instance.setGdpr(hasConsent);
_scaffoldMessengerKey.currentState?.showSnackBar(
SnackBar(content: Text('GDPR ${hasConsent ? 'T' : 'F'} 적용')),
);
}
Future<void> _setCoppaFixed(bool isChildDirected) async {
await AdWhaleMediationAds.instance.setCoppa(isChildDirected);
_scaffoldMessengerKey.currentState?.showSnackBar(
SnackBar(content: Text('COPPA ${isChildDirected ? 'T' : 'F'} 적용')),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
scaffoldMessengerKey: _scaffoldMessengerKey,
navigatorKey: _navigatorKey,
home: Scaffold(
appBar: AppBar(title: const Text('AdWhale Flutter Example App')),
body: Column(
children: [
Expanded(
child: Container(
color: Colors.amber,
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Styled Template section (reference-aligned)
// Style toggle removed
ElevatedButton(
onPressed: _showInterstitialAd,
child: const Text('전면 광고 호출'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _showRewardedAd,
child: const Text('리워드 광고 호출'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
_navigatorKey.currentState?.push(
MaterialPageRoute(
builder: (BuildContext context) => const ForegroundTestPage(),
),
);
},
child: const Text('포그라운드 전환 테스트'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _createAppOpenAd,
child: const Text('앱오프닝 광고 호출'),
),
const SizedBox(height: 16),
// 버튼 클릭 시 enum으로 배너 광고 호출
ElevatedButton(
onPressed: () => _showBannerAd(BannerHeightEnum.BANNER320x50),
child: const Text('배너 320×50'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => _showBannerAd(BannerHeightEnum.BANNER320x100),
child: const Text('배너 320×100'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => _showBannerAd(BannerHeightEnum.BANNER300x250),
child: const Text('배너 300×250'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => _showBannerAd(BannerHeightEnum.BANNER250x250),
child: const Text('배너 250×250'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
_navigatorKey.currentState?.push(
MaterialPageRoute(
builder: (BuildContext context) => NativeTestPage(),
),
);
},
child: const Text('네이티브 테스트 화면 이동'),
),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: _requestGdpr,
child: const Text('GDPR호출'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: _resetGdpr,
child: const Text('GDPR리셋'),
),
),
],
),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () => _setGdprFixed(true),
child: const Text('GDPR T'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: () => _setGdprFixed(false),
child: const Text('GDPR F'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: () => _setCoppaFixed(true),
child: const Text('COPPA T'),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed: () => _setCoppaFixed(false),
child: const Text('COPPA F'),
),
),
],
),
],
),
),
),
),
),
// 배너 광고가 로드되면 하단에 표시
_banner == null
? const SizedBox.shrink()
: SizedBox(
height: _bannerHeightFor(_banner!),
child: AdWidget(
key: ValueKey(_banner!.hashCode),
ad: _banner!,
),
),
],
),
),
);
}
@override
void dispose() {
_banner?.dispose();
super.dispose();
}
double _bannerHeightFor(BannerAd ad) {
switch (ad.adInfo.bannerHeight) {
case BannerHeightEnum.BANNER320x50:
return 50.0;
case BannerHeightEnum.BANNER320x100:
return 100.0;
case BannerHeightEnum.BANNER300x250:
return 250.0;
case BannerHeightEnum.BANNER250x250:
return 250.0;
case BannerHeightEnum.ADAPTIVE_ANCHOR:
return 50.0;
}
}
}