adquanta_ads_sdk 1.7.0
adquanta_ads_sdk: ^1.7.0 copied to clipboard
AdQuanta Ads SDK for Flutter - 专业的移动广告聚合SDK
AdQuanta Ads SDK for Flutter #
AdQuanta Ads SDK 是一个功能强大的移动广告聚合SDK,支持多种广告形式,帮助开发者轻松集成广告功能,实现收益最大化。
功能特性 #
- ✅ 多种广告形式:支持 Banner、Splash、Rewarded、Android Interstitial、Android Native 和 Android GAME
- ✅ 统一API接口:提供简洁统一的API,降低集成复杂度
- ✅ Android 广告能力:Banner、Splash、Rewarded、Interstitial、Native 和 GAME 均由 Android 原生桥接提供
- ✅ 完善的回调:提供完整的广告生命周期回调,便于业务处理
- ✅ 隐私合规:支持GDPR、CCPA等隐私合规配置
系统要求 #
- Flutter 3.3.0 或更高版本
- Android API Level 24 (Android 7.0) 或更高版本
本插件自 1.7.0 起仅在 Android 请求和展示广告。iOS、Web 和桌面仍可安全依赖、编译和启动,
但不会注册 AdQuanta 原生插件、请求广告或展示广告。移除本插件不会提高宿主的 iOS 最低版本;
宿主的其他 Pods 仍可能有各自的版本要求。
安装 #
在您的 pubspec.yaml 文件中添加依赖:
dependencies:
adquanta_ads_sdk: ^1.7.0
然后运行:
flutter pub get
快速开始 #
1. 初始化 SDK #
在应用启动时初始化 SDK(建议在 main() 函数中):
import 'package:adquanta_ads_sdk/adquanta_ads_sdk.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (AdquantaSdk.isSupported) {
await AdquantaSdk.init(
appId: 'YOUR_APP_ID',
userId: 'OPTIONAL_HOST_USER_ID',
gameEnabled: false,
);
}
runApp(MyApp());
}
在非 Android 平台,AdquantaSdk.isSupported 为 false。基础 API 返回安全默认值;广告对象和
Widget 不会触发 MissingPluginException,加载回调会收到一次错误码 -2。
2. 使用 Banner 广告 #
import 'package:adquanta_ads_sdk/adquanta_ads_sdk.dart';
class MyBannerWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AdquantaBanner(
adUnitId: 'YOUR_BANNER_AD_UNIT_ID',
padding: const EdgeInsets.only(bottom: 12),
listener: MyBannerListener(),
);
}
}
class MyBannerListener extends AdquantaBannerListener {
@override
void onAdLoaded(AdquantaAdInfo adInfo) {
print('Banner 广告加载成功: ${adInfo.adSourceName}');
}
@override
void onAdLoadFailed(AdquantaAdError error) {
print('Banner 广告加载失败: ${error.message}');
}
@override
void onAdClicked(AdquantaAdInfo adInfo) {
print('Banner 广告被点击');
}
@override
void onAdImpression(AdquantaAdInfo adInfo) {
print('Banner 广告展示成功');
}
@override
void onAdClosed(AdquantaAdInfo adInfo) {
print('Banner 广告关闭');
}
}
AdquantaBanner starts collapsed, reveals itself after a successful load, and
collapses itself after a load or show failure. The optional padding is part of
the collapsible area, so host applications do not need to manage Banner size or
visibility. Listeners are optional and should only observe lifecycle events.
3. 使用 Splash 开屏广告 #
import 'package:adquanta_ads_sdk/adquanta_ads_sdk.dart';
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
late AdquantaSplash _splashAd;
@override
void initState() {
super.initState();
_splashAd = AdquantaSplash(
adUnitId: 'YOUR_SPLASH_AD_UNIT_ID',
listener: MySplashListener(),
);
_splashAd.loadAd();
}
@override
void dispose() {
_splashAd.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(child: CircularProgressIndicator()),
),
);
}
}
class MySplashListener extends AdquantaSplashListener {
@override
void onAdLoaded(AdquantaAdInfo adInfo) {
// 广告加载成功,显示开屏广告
// 注意:实际的显示逻辑需要在 Flutter 端处理
print('Splash 广告加载成功');
}
@override
void onAdLoadFailed(AdquantaAdError error) {
// 广告加载失败,跳转到主界面
print('Splash 广告加载失败: ${error.message}');
}
@override
void onAdClosed(AdquantaAdInfo adInfo) {
// 广告关闭,跳转到主界面
print('Splash 广告关闭');
}
@override
void onAdClicked(AdquantaAdInfo adInfo) {
print('Splash 广告被点击');
}
@override
void onAdImpression(AdquantaAdInfo adInfo) {
print('Splash 广告展示成功');
}
}
4. 使用 Rewarded 激励视频广告 #
import 'package:adquanta_ads_sdk/adquanta_ads_sdk.dart';
class RewardedAdExample extends StatefulWidget {
@override
_RewardedAdExampleState createState() => _RewardedAdExampleState();
}
class _RewardedAdExampleState extends State<RewardedAdExample> {
late AdquantaRewarded _rewardedAd;
@override
void initState() {
super.initState();
_rewardedAd = AdquantaRewarded(
adUnitId: 'YOUR_REWARDED_AD_UNIT_ID',
listener: MyRewardedListener(),
);
_rewardedAd.loadAd();
}
Future<void> _showRewardedAd() async {
final isReady = await _rewardedAd.isReady();
if (isReady) {
await _rewardedAd.showAd();
} else {
print('Rewarded 广告还未准备好');
}
}
@override
void dispose() {
_rewardedAd.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('激励视频广告')),
body: Center(
child: ElevatedButton(
onPressed: _showRewardedAd,
child: Text('观看视频获得奖励'),
),
),
);
}
}
class MyRewardedListener extends AdquantaRewardedListener {
@override
void onAdLoaded(AdquantaAdInfo adInfo) {
print('Rewarded 广告加载成功');
}
@override
void onAdLoadFailed(AdquantaAdError error) {
print('Rewarded 广告加载失败: ${error.message}');
}
@override
void onAdReward(AdquantaAdInfo adInfo) {
print('获得奖励: ${adInfo.currencyName} ${adInfo.amount}');
// 在这里处理奖励逻辑
}
@override
void onAdClosed(AdquantaAdInfo adInfo) {
print('Rewarded 广告关闭');
// 可以重新加载广告
}
@override
void onAdClicked(AdquantaAdInfo adInfo) {
print('Rewarded 广告被点击');
}
@override
void onAdImpression(AdquantaAdInfo adInfo) {
print('Rewarded 广告展示成功');
}
@override
void onAdVideoStart(AdquantaAdInfo adInfo) {
print('视频开始播放');
}
@override
void onAdVideoEnd(AdquantaAdInfo adInfo) {
print('视频播放结束');
}
@override
void onAdVideoError(AdquantaAdInfo adInfo, AdquantaAdError error) {
print('视频播放错误: ${error.message}');
}
}
5. 使用 Native 原生广告(Android) #
AdquantaNative 是 Android PlatformView。Widget 默认自动加载,并在加载成功后调用底层
showAd(container);加载或展示失败时自动折叠。关闭 autoShow 后可由 controller 显式控制展示。
class NativeAdExample extends StatefulWidget {
const NativeAdExample({super.key});
@override
State<NativeAdExample> createState() => _NativeAdExampleState();
}
class _NativeAdExampleState extends State<NativeAdExample> {
final _controller = AdquantaNativeController();
@override
Widget build(BuildContext context) {
return Column(
children: [
AdquantaNative(
key: const ValueKey('feed_native'),
adUnitId: 'feed_native',
height: 320,
controller: _controller,
autoShow: false,
listener: MyNativeListener(),
),
ElevatedButton(
onPressed: () async {
if (await _controller.isReady()) {
await _controller.showAd();
} else {
await _controller.loadAd();
}
},
child: const Text('加载或展示 Native'),
),
],
);
}
}
class MyNativeListener extends AdquantaAdListener {
@override
void onAdLoaded(AdquantaAdInfo adInfo) {
print('Native 加载并渲染成功: ${adInfo.provider}');
}
@override
void onAdLoadFailed(AdquantaAdError error) {
print('Native 加载失败: ${error.message}');
}
@override
void onAdShowFailed(AdquantaAdError error, AdquantaAdInfo adInfo) {
print('Native 渲染失败: ${error.message}');
}
@override
void onAdClicked(AdquantaAdInfo adInfo) {
print('Native 被点击');
}
@override
void onAdImpression(AdquantaAdInfo adInfo) {
print('Native 产生展示');
}
}
Native 的 Provider 选择、素材渲染、点击和曝光由 Android AdQuanta SDK 负责,Flutter 插件不再维护
AdMob/TradPlus 专用布局。adUnitId 是 PlatformView 创建期参数;动态切换广告位时请同步更换 Key。
6. 使用插屏广告(Android) #
final interstitial = AdquantaInterstitial(
adUnitId: 'interstitial_slot',
listener: MyInterstitialListener(),
);
await interstitial.loadAd();
if (await interstitial.isReady()) {
await interstitial.showAd();
}
// 在所属页面销毁时调用
await interstitial.dispose();
插屏回调使用通用 AdquantaAdListener,包括加载、展示失败、点击、展示和关闭事件。
7. 使用 GAME(Android) #
AdquantaGame(
key: const ValueKey('game_center_tab'),
adUnitId: 'game_slot',
height: 96,
androidDrawableName: 'game_center_entry',
listener: MyGameListener(),
)
AdquantaGame 在 EventChannel ready 后自动加载,使用通用 AdquantaAdListener。普通 GAME 不传
androidDrawableName;Game Center 入口传宿主 drawable 名称,用户点击底层真实 View 后进入游戏中心。
class MyGameListener extends AdquantaAdListener {
@override
void onAdLoaded(AdquantaAdInfo adInfo) {
print('GAME 加载成功');
}
@override
void onAdLoadFailed(AdquantaAdError error) {
print('GAME 加载失败: ${error.message}');
}
}
启用 GAME 时,首次初始化必须传 gameEnabled: true:
await AdquantaSdk.init(
appId: 'YOUR_APP_ID',
gameEnabled: true,
);
GAME 是 Android-only 能力。MiniGame AAR 及其运行时依赖由宿主 Flutter App 的
android/app 工程按 Android SDK 集成文档显式提供;本插件不会打包 Android SDK 声明为
compileOnly 的依赖。
将宿主设计的入口图片放入
android/app/src/main/res/drawable/game_center_entry.xml(也可使用 PNG/WebP)。开启
shrinkResources 时,在 android/app/src/main/res/raw/keep.xml 中保留动态解析的资源:
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:tools="http://schemas.android.com/tools"
tools:keep="@drawable/game_center_entry" />
MiniGame AAR 不随 Flutter 插件分发。开启 Game Center 的宿主需从 MiniGame 官方渠道获取
unite-sdk-1.1.0.aar,放入 android/app/libs/minigame/,并在 App 模块声明:
implementation files("libs/minigame/unite-sdk-1.1.0.aar")
implementation "androidx.core:core-ktx:1.17.0"
implementation "androidx.appcompat:appcompat:1.7.1"
implementation "com.google.android.material:material:1.13.0"
implementation "androidx.browser:browser:1.8.0"
implementation "io.coil-kt:coil:2.6.0"
implementation "io.coil-kt:coil-svg:2.6.0"
implementation "androidx.media3:media3-exoplayer:1.4.1"
implementation "androidx.media3:media3-ui:1.4.1"
adUnitId 和 androidDrawableName 都是 PlatformView 创建期参数;动态切换时必须使用包含这些参数的
新 Key。drawable 名非空但资源不存在时,PlatformView 创建会返回参数错误;未传 drawable 时插件不判断
底层路由,失败由 Android SDK 的 onAdLoadFailed 上报。
API 参考 #
AdquantaSdk #
SDK 主类,用于初始化和配置。
方法
init({required String appId, String? userId, bool gameEnabled = false, ...})- 初始化 SDKsetLogLevel(int level)- 设置日志级别 (0=关闭, 1=错误, 2=警告, 3=信息, 4=调试)setGDPRDataCollection(bool canDataCollection)- 设置 GDPR 数据收集setCCPADoNotSell(bool doNotSell)- 设置 CCPA 不销售数据setCOPPAIsAgeRestrictedUser(bool isAgeRestrictedUser)- 设置 COPPA 年龄限制setLGPDIsConsentEnabled(bool isConsentEnabled)- 设置 LGPD 同意状态setDevAllowTracking(bool allowTracking)- 设置是否允许追踪
AdquantaBanner #
Banner 广告类,是一个 Widget。
属性
adUnitId- 广告单元 IDlistener- 广告监听器width- Banner 宽度(可选)height- Banner 高度(可选,默认 50)
Banner 创建后自动加载;尺寸由 AdquantaAdInfo.widthDp/heightDp 或内部 View 测量结果更新。
AdquantaSplash #
Splash 开屏广告类。
方法
loadAd({double? bottomViewHeight})- 加载广告showAd()- 显示广告dispose()- 销毁广告实例
AdquantaRewarded #
Rewarded 激励视频广告类。
方法
loadAd()- 加载广告showAd()- 显示广告isReady()- 检查广告是否已准备好dispose()- 销毁广告实例
AdquantaNative #
Android Native 广告 PlatformView。
属性
adUnitId- AdQuanta Native Slot IDheight- PlatformView 高度listener- 通用AdquantaAdListenercontroller- 可选AdquantaNativeControllerautoLoad- Widget 创建后是否自动加载,默认trueautoShow- 加载成功后是否自动展示,默认truepadding- 可选外边距
方法
AdquantaNativeController.loadAd()- 发起加载AdquantaNativeController.isReady()- 查询底层 Native 是否可展示AdquantaNativeController.showAd()- 展示到插件持有的 Native 容器
AdquantaGame #
Android GAME PlatformView,EventChannel ready 后自动加载。
属性
adUnitId- AdQuanta Game Slot IDandroidDrawableName- 可选宿主 Android drawable 资源名;Game Center Slot 使用height- PlatformView 高度listener- 通用AdquantaAdListenerpadding- 可选外边距
从旧 Android 桥接迁移 #
| 旧 API/行为 | 1.7.0 + Android SDK 0.0.15 |
|---|---|
AdquantaSdk.init(appId: ...) |
可增加 userId;使用 GAME 时增加 gameEnabled: true |
Interstitial/Rewarded showAd(sceneId: ...) |
showAd();底层 0.0.15 不再接收 sceneId |
AdquantaNativeListener |
通用 AdquantaAdListener |
Native 的 sceneId、AdMob/TradPlus layout name |
删除;渲染完全由底层 AdquantaNative 负责 |
| Native 仅自动渲染 | controller 新增 isReady()/showAd(),并可设置 autoShow: false |
AdquantaGameCenter、AdquantaGameListener、controller 主动打开 |
统一为 AdquantaGame + AdquantaAdListener,由用户点击真实 View 打开 |
gameCenterTitle / androidGameCenterDrawableName |
删除 title;drawable 改为 androidDrawableName |
Banner onAdRequest/onAdSizeChanged |
删除;Widget 内部消费 widthDp/heightDp 和测量事件 |
Native 的 adUnitId,以及 GAME 的 adUnitId/androidDrawableName,都是 PlatformView 创建期身份参数。
运行时切换这些值时,必须同时使用新的 Key 来触发旧 View dispose 和新 View 创建。
Android SDK 辅助 API #
以下 API 仅在 Android 调用原生实现;非 Android 会安全返回默认值:
await AdquantaSdk.setGoogleAnalyticsEnabled(true);
final analyticsEnabled = await AdquantaSdk.isGoogleAnalyticsEnabled();
final sdkVersion = await AdquantaSdk.getVersion();
final privacyOptionsSupported = await AdquantaSdk.isPrivacyOptionsSupported();
Publisher Signals(兼容扩展) #
AdquantaSdk.setPublisherSignals() 保持现有行为,用于 TradPlus Banner impression 与
InMobi Publisher Signals 兼容上报。该 API 直接依赖相关三方 SDK,不属于 Android
ads-sdk 的通用桥接能力;新接入不应将其作为广告生命周期实现的参考。
隐私合规配置 #
初始化时通过以下参数传入隐私默认值;需要用户随时调整 UMP 选项时,调用
AdquantaSdk.showPrivacyOptionsForm():
await AdquantaSdk.init(
appId: 'YOUR_APP_ID',
underAgeOfConsent: false,
ageRestrictedUser: false,
lgpdAllowDataUpload: true,
);
final canRequestAds = await AdquantaSdk.showPrivacyOptionsForm();
常见问题 #
1. 广告无法加载 #
- 检查 App ID 和 Ad Unit ID 是否正确
- 确保网络连接正常
- 确认在应用启动时调用了
AdquantaSdk.init()
2. Banner 广告不显示 #
- 确保 Banner Widget 已添加到 Widget 树中
- 检查广告尺寸设置是否正确
- 确保容器有足够的空间显示广告
3. Rewarded 广告无法显示 #
- 在显示前使用
isReady()检查广告是否已准备好 - 确保广告加载完成后再调用
showAd()
更新日志 #
Version 0.0.1 #
- 初始版本发布
- 支持 Banner、Splash、Rewarded 广告
- 支持 iOS 和 Android 平台
- 提供统一的 API 接口
许可证 #
本项目采用 GPL-3.0 许可证,详见 LICENSE 文件。
技术支持 #
如有问题或建议,请联系技术支持团队:support@adoptrack.com
Funlink (Android / TradPlus custom source) #
The Android plugin can package Funlink as a TradPlus custom ad source. This
preserves the existing Flutter API: Banner, Splash, Rewarded, and any future
formats continue to be requested through AdquantaSdk; no Funlink method
channel or MainApplication initialization is needed.
Because Android Gradle cannot bundle direct local AAR dependencies from a
Flutter plugin's Android library module, add the following vendor artifacts to
the consuming app at android/app/libs/funlink/:
funlink_2.9.0_78468644_release.aarfunlink_adapter_custom_tradplus_2.9.0_78468644_release.aar
Then add the following to the consuming app's android/app/build.gradle.kts
dependencies block (Groovy projects use equivalent implementation files(...)
statements):
implementation(files("libs/funlink/funlink_2.9.0_78468644_release.aar"))
implementation(files("libs/funlink/funlink_adapter_custom_tradplus_2.9.0_78468644_release.aar"))
implementation("com.google.android.gms:play-services-ads-identifier:18.2.0")
In the TradPlus dashboard, create a custom source with these settings:
| Format | Adapter class |
|---|---|
| Rewarded | com.fl.saas.custom.tradplus.TPCustomRewardAdapter |
| Interstitial | com.fl.saas.custom.tradplus.TPCustomInterstitialAdapter |
| Banner | com.fl.saas.custom.tradplus.TPCustomBannerAdapter |
| Native | com.fl.saas.custom.tradplus.TPCustomNativeAdapter |
| Splash | com.fl.saas.custom.tradplus.TPCustomSpreadAdapter |
Use the adapter JSON exactly as follows, substituting the Funlink console IDs:
{"appId":"FUNLINK_APP_ID","placementId":"FUNLINK_PLACEMENT_ID"}
The custom adapter initializes Funlink when TradPlus requests it. Do not call
FLConfig.init from Application.onCreate: doing so can run before consent
and duplicates the adapter-managed initialization.
Funlink's supplied core AAR contributes additional Android manifest entries,
including READ_PHONE_STATE and QUERY_ALL_PACKAGES, besides the documented
network permissions. Review their Google Play policy eligibility with Funlink
before a production release.