# ADJgSdk_Flutter
**Repository Path**: jiguang-official/adjg-sdk_flutter
## Basic Information
- **Project Name**: ADJgSdk_Flutter
- **Description**: 广告聚合ssp flutter版本
- **Primary Language**: Dart
- **License**: GPL-3.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 3
- **Forks**: 0
- **Created**: 2022-08-15
- **Last Updated**: 2025-10-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# ad_jg_flutter_sdk
[TOC]
## 1.1 概述
尊敬的开发者朋友,欢迎您使用极光广告Flutter插件。通过本文档,您可以在几分钟之内轻松完成广告的集成过程。
操作系统: iOS 12.0 及以上版本,Android 4.4 及以上版本,
运行设备:iPhone (iPad上可能部分广告正常展示,但是存在填充很低或者平台不支持等问题,建议不要在iPad上展示广告),Android
## 2.1 SDK导入
首先需要导入主SDK
```dart
dependencies:
adjg_flutter: {library version}
```
然后需要导入各平台SDK,
### 2.1.1 iOS在项目的podfile中增加如下内容,可以根据实际需要选择性导入平台
```ruby
pod 'ADJgSDK','~> 4.0.1.06138' # 主SDK 必选
pod 'ADJgSDK/ADJgSDKPlatforms/tianmu' # 天目 必选
pod 'ADJgSDK/ADJgSDKPlatforms/jgads' # 极光Ads
pod 'ADJgSDK/ADJgSDKPlatforms/gdt' # 优量汇(广点通)
pod 'ADJgSDK/ADJgSDKPlatforms/ks' # 快手
pod 'ADJgSDK/ADJgSDKPlatforms/baidu' # 百度
pod 'ADJgSDK/ADJgSDKPlatforms/beizi' # 倍孜
pod 'ADJgSDK/ADJgSDKPlatforms/huiying' # 汇盈
pod 'ADJgSDK/ADJgSDKPlatforms/octopus' # 章鱼
# ab二选一
# a.不需要gromore
pod 'ADJgSDK/ADJgSDKPlatforms/bu' # 穿山甲(头条)
# b.需要gromore
# pod 'ADJgSDK/ADJgSDKPlatforms/bu-without' # 穿山甲(头条)
# pod 'ADJgSDK/ADJgSDKPlatforms/gromore' # gromore
```
### 2.1.2 Android在项目中增加如下内容,可以根据实际需要选择性导入平台
#### 2.1.2.1. 在android根目录build.gradle中添加天目仓库
```java
allprojects {
repositories {
...
google()
jcenter()
mavenCentral()
//天目渠道maven地址
maven { url "https://maven.admobile.top/repository/maven-releases/" }
//未导入汇量渠道可不加maven地址
maven { url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_support/" }
}
}
```
#### 2.1.2.2. OAID支持
导入安全联盟的OAID支持库 oaid_sdk_1.0.25.aar,可在Demo的libs目录下找到,强烈建议使用和Demo中一样版本的OAID库(包括项目中已存在的依赖的oaid版本);
将Demo中assets文件夹下的supplierconfig.json文件复制到自己的assets目录下并按照supplierconfig.json文件中的说明进行OAID的 AppId 配置,supplierconfig.json文件名不可修改;
#### 2.1.2.3. 在android/app目录build.gradle中添加相关依赖
```java
// Androidx支持库
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.0.0-rc01'
// ADJg主SDK ,必须的
implementation "cn.jiguang.sdk.ad:core:4.0.1.06033"
// OAID1.0.25版本适配器不支持其它版本,ADJgSdk获取oaid使用
implementation "cn.jiguang.sdk.ad:oaid:1.0.25.12122"
// OAID库1.0.25
implementation(name: 'oaid_sdk_1.0.25', ext: 'aar')
// 极光Ads适配器,必须的
implementation "cn.jiguang.sdk.ad.adapter:jgads:3.0.1.3.10151"
// 天目适配器,必须的
implementation "cn.jiguang.sdk.ad.adapter:tianmu:3.0.3.3.10131"
// 优量汇适配器,可选的
implementation "cn.jiguang.sdk.ad.adapter:gdt:4.660.1530.10141"
// 头条适配器,可选的
implementation "cn.jiguang.sdk.ad.adapter:toutiao:7.1.3.2.10141"
// Gromore适配器,可选的
implementation 'cn.jiguang.sdk.ad.adapter:gromore-without:7.0.0.8.08261'
// 百度适配器,仅支持androidx版本,可选的
implementation "cn.jiguang.sdk.ad.adapter:baidu-androidx:9.42.10141"
// 快手适配器,可选的
implementation "cn.jiguang.sdk.ad.adapter:ksadbase:4.9.20.1.10141"
// 倍孜适配器,可选的
implementation 'cn.jiguang.sdk.ad.adapter:beizi:5.2.2.0.10141'
// 章鱼适配器,可选的
implementation 'cn.jiguang.sdk.ad.adapter:octopus:2.5.10.5.10141'
// 汇盈适配器
implementation 'cn.jiguang.sdk.ad.adapter:huiying:1.5.3.19.10151'
// 汇盈sdk必须引入内容
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.googlecode.android-query:android-query:0.25.9'
implementation 'com.android.support:cardview-v7:21.0.0'
```
#### 2.1.2.4. 广告位创建注意事项
由于使用flutter方式对接,信息流广告可能存在无法展示广告问题,需要在创建优量汇、百度、快手渠道时,创建接近10:9比例的广告样式,可以达到最好的展示效果,否则会出现留白情况。
## 3.1 工程环境配置
### 3.1.1 IOS 工程环境配置
#### 3.1.1.1. info.plist 添加支持 Http访问字段
```
NSAppTransportSecurity
NSAllowsArbitraryLoads
```
#### 3.1.1.2. Info.plist 添加定位权限字段(使用ADMobGenLocation可不设置)
```
NSLocationWhenInUseUsageDescription
NSLocationAlwaysAndWhenInUseUsageDeion
```
#### 3.1.1.3. Info.plist 添加获取本地网络权限字段
```
Privacy - Local Network Usage Description
广告投放及广告监测归因、反作弊
Bonjour services
_apple-mobdev2._tcp.local
```
#### 3.1.1.4. Info.plist推荐设置白名单,可提高广告收益
```
LSApplicationQueriesSchemes
com.suning.SuningEBuy
openapp.jdmobile
openjd
jdmobile
vmall
vipshop
suning
yohobuy
kaola
yanxuan
wbmain
dianping
imeituan
beibeiapp
taobao
tmall
wireless1688
tbopen
taobaolite
taobaoliveshare
koubei
eleme
alipays
kfcapplinkurl
pddopen
pinduoduo
mogujie
lianjiabeike
lianjia
openanjuke
zhuanzhuan
farfetchCN
weibo
xhsdiscover
uclink
momochat
blued
zhihu
baiduboxapp
yidui
sinanews
snssdk141
newsapp
igetApp
kuaikan
youku
snssdk1128
gifshow
snssdk1112
miguvideo
iqiyi
bilibili
tenvideo
baiduhaokan
yykiwi
qqmusic
orpheus
kugouURL
qmkege
changba
iting
ctrip
QunarAlipay
diditaxi
didicommon
taobaotravel
OneTravel
kfhxztravel
gengmei
app.soyoung
```
### 3.1.2 Android 工程环境配置
#### 3.1.2.1 权限配置
```java
```
#### 3.1.2.2 FileProvider配置
适配Anroid7.0以及以上,请在AndroidManifest中添加如下代码:
如果支持库是support
```java
```
如果支持库为androidx
```java
```
在res/xml目录下(如果xml目录不存在需要手动创建),新建xml文件adjg_file_paths,在该文件中加入如下配置,如果存在相同android:authorities的provider,请将paths标签中的路劲配置到自己的xml文件中:
```java
```
#### 3.1.2.3 网络配置
需要在 AndroidManifest.xml 添加依赖声明uses-library android:name="org.apache.http.legacy" android:required="false", 且 application标签中添加 android:usesCleartextTraffic="true",适配网络http请求,否则 SDK可能无法正常工作,接入代码示例如下:
```java
... ...
```
#### 3.1.2.4 混淆配置
```java
# ADJgSdk混淆
-dontwarn cn.jiguang.jgssp.**
-dontwarn org.apache.commons.**
-keep class cn.jiguang.jgssp.**{public *;}
-keep class com.android.**{*;}
-keep class com.ciba.**{ *; }
-keep class org.apache.**{*;}
# okhttp
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
# OAID混淆
-keep class com.bun.miitmdid.core.** {*;}
-keep class XI.CA.XI.**{*;}
-keep class XI.K0.XI.**{*;}
-keep class XI.XI.K0.**{*;}
-keep class XI.vs.K0.**{*;}
-keep class XI.xo.XI.XI.**{*;}
-keep class com.asus.msa.SupplementaryDID.**{*;}
-keep class com.asus.msa.sdid.**{*;}
-keep class com.bun.lib.**{*;}
-keep class com.bun.miitmdid.**{*;}
-keep class com.huawei.hms.ads.identifier.**{*;}
-keep class com.samsung.android.deviceidservice.**{*;}
-keep class org.json.**{*;}
-keep public class com.netease.nis.sdkwrapper.Utils {public ;}
# 广点通广告平台混淆
-keep class com.qq.e.** {public protected *;}
-keep class MTT.ThirdAppInfoNew {*;}
-keep class com.tencent.** {*;}
# 百度广告SDK混淆
-keepclassmembers class * extends android.app.Activity { public void *(android.view.View);}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class com.baidu.mobads.** { *; }
-keep class com.baidu.mobad.** { *; }
# 头条广告平台混淆
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep class com.bytedance.sdk.openadsdk.** {*;}
-keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;}
-keep class com.pgl.sys.ces.* {*;}
-keep class com.bytedance.embed_dr.** {*;}
-keep class com.bytedance.embedapplog.** {*;}
# mintegral广告平台混淆
-dontwarn com.mintegral.**
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.mbridge.** {*; }
-keep interface com.mbridge.** {*; }
-keep class android.support.v4.** { *; }
-dontwarn com.mbridge.**
-keep class **.R$* { public static final int mbridge*; }
# 快手广告平台混淆
-keep class org.chromium.** { *; }
-keep class aegon.chrome.** { *; }
-keep class com.kwai.**{ *; }
-keep class com.kwad.**{ *; }
-dontwarn com.kwai.**
-dontwarn com.kwad.**
-dontwarn com.ksad.**
-dontwarn aegon.chrome.**
-keep class com.kwad.sdk.** { *;}
-keep class com.ksad.download.** { *;}
-keep class com.kwai.filedownloader.** { *;}
-keepclasseswithmembernames class * { native ;}
# 极光Ads混淆
-keep class com.junion.**{ *; }
# 天目广告
-keep class com.tianmu.**{ *; }
# Jgid的混淆规则
-keep class jgssp.com.** { *; }
-keep interface jgssp.com.** { *; }
-keep interface cn.jiguang.jgssp.oaid.IGetter{public *;}
# 倍孜Beizi广告混淆
-dontwarn android.app.**
-dontwarn android.support.**
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-dontwarn org.apache.**
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-dontwarn com.beizi.fusion.**
-dontwarn com.beizi.ad.**
-keep class com.beizi.fusion.** {*; }
-keep class com.beizi.ad.** {*; }
# 章鱼的混淆规则
-dontwarn com.octopus.ad.**
-keep class com.octopus.ad.** {*;}
# 汇盈的混淆规则
-keep class cn.haorui.sdk.** { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
```
#### 3.1.2.5 注册java与flutter交互代码
[参考资料](https://developers.google.cn/ad-manager/mobile-ads-sdk/flutter/native/get-started?hl=zh-cn)
```java
public class MainActivity extends FlutterActivity {
...
@Override
public void configureFlutterEngine(FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
...
Log.d("configureFlutterEngine", "init");
flutterEngine.getPlugins().add(new ADJgMobileAdsPlugin());
ADJgMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "adFactoryExample");
...
}
@Override
public void cleanUpFlutterEngine(FlutterEngine flutterEngine) {
}
...
}
```
#### 3.1.2.6 导入插件后的异常处理
Q:Plugin project :xxx not found. Please update settings.gradle
A:可参考demo中的settings.gradle,将配置拷贝到项目中
## 3.2 iOS14适配
由于iOS14中对于权限和隐私内容有一定程度的修改,而且和广告业务关系较大,请按照如下步骤适配,如果未适配。不会导致运行异常或者崩溃等情况,但是会一定程度上影响广告收入。敬请知悉。
1. 应用编译环境升级至 Xcode 12.0 及以上版本;
2. 升级ADJgSDK 3.6.2及以上版本;
3. 设置SKAdNetwork和IDFA权限;
### 3.2.1 获取App Tracking Transparency授权(弹窗授权获取IDFA)
从 iOS 14 开始,在应用程序调用 App Tracking Transparency 向用户提跟踪授权请求之前,IDFA 将不可用。
1. 更新 Info.plist,添加 NSUserTrackingUsageDescription 字段和自定义文案描述。
弹窗小字文案建议:
- `获取标记权限向您提供更优质、安全的个性化服务及内容,未经同意我们不会用于其他目的;开启后,您也可以前往系统“设置-隐私 ”中随时关闭。`
- `获取IDFA标记权限向您提供更优质、安全的个性化服务及内容;开启后,您也可以前往系统“设置-隐私 ”中随时关闭。`
```
NSUserTrackingUsageDescription
获取标记权限向您提供更优质、安全的个性化服务及内容,未经同意我们不会用于其他目的;开启后,您也可以前往系统“设置-隐私 ”中随时关闭
```
1. 向用户申请权限。
```
#import
#import
...
- (void)requestIDFA {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
// 无需对授权状态进行处理
}];
}
// 建议启动App用户同意协议后就获取权限或者请求广告前获取
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 针对iOS15中不弹窗被拒解决方案,方案1:经测试可能无效
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 用户同意协议后获取
//[self requestIDFA];
//});
}
// 方案2:根据官方文档调整权限申请时机
// 根据官方开发文档选择在此方法中进行权限申请
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 用户同意协议后获取
[self requestIDFA];
}
// 建议方案1与2一起使用,可正常通过审核。
```
### 3.2.2 SKAdNetwork
SKAdNetwork 是接收iOS端营销推广活动归因数据的一种方法。
1. 将下列SKAdNetwork ID(供参考,需以穿山甲官网为准)添加到 info.plist 中,以保证 SKAdNetwork 的正确运行。根据对接平台添加相应SKAdNetworkID,若无对接平台SKNetworkID则无需添加。
```
SKAdNetworkItems
// 穿山甲广告(ADJgBU)
SKAdNetworkIdentifier
238da6jt44.skadnetwork
SKAdNetworkIdentifier
22mmun2rn5.skadnetwork
```
## 4.1 主SDK初始化
```dart
AdJgFlutterSdk.initSdk(appid: "appid");
```
## 4.2 开屏广告
### 4.2.1 开屏广告(跳转至原生页面加载并展示)
```dart
class SplashPage extends StatefulWidget {
@override
State createState() => _SplashState();
}
class _SplashState extends State {
ADJgSplashAd _splashAd;
@override
Widget build(BuildContext context) {
showSplashAd();
return Scaffold(
appBar: AppBar(
title: Text("Splash"),
),
body: Center(
),
);
}
// 开屏
// 显示开屏广告请保证当时app内没有其他地方显示开屏广告,否则会有冲突
void showSplashAd() {
if(_splashAd != null) {
return;
}
// posId:广告位id,
// imgName:背景名称,
// imgLogoName:底部logo名称,
// isRepeatApplyPermission:用户拒绝权限后是否允许重复读取:true允许,false禁止,
// isApplyPermission:动态申请权限:true允许,false禁止,
_splashAd = ADJgSplashAd(posId: "posid", imgName: "splash_placeholder", imgLogoName: "splash_bottom_icon", isRepeatApplyPermission: false, isApplyPermission:true);
_splashAd.onClosed = (AdInfo adInfo) {
print("开屏广告关闭了");
// 在加载失败和关闭回调后关闭广告
releaseSplashAd();
};
_splashAd.onFailed = (AdErrorInfo adErrorInfo) {
print("开屏广告失败了");
// 在加载失败和关闭回调后关闭广告
releaseSplashAd();
};
_splashAd.onExposed = (AdInfo adInfo) { print("开屏广告曝光了"); };
_splashAd.onSucced = (AdInfo adInfo) { print("开屏广告成功了"); };
_splashAd.onClicked = (AdInfo adInfo) { print("开屏广告点击了"); };
_splashAd.loadAndShow();
}
void releaseSplashAd() {
_splashAd?.release();
_splashAd = null;
}
@override
void dispose() {
releaseSplashAd();
super.dispose();
}
}
```
### 4.2.2 开屏广告(flutter原生加载展示分离)
```dart
class _SplashLoadShowSeparateState extends State {
ADJgSplashAdLoadShowSeparate? _adJgFlutterSplashAd;
bool _hasInitBanner = false;
@override
Widget build(BuildContext context) {
if (_adJgFlutterSplashAd == null && _hasInitBanner == false) {
MediaQueryData queryData = MediaQuery.of(context);
_hasInitBanner = true;
var width = queryData.size.width;
var height = queryData.size.height;
_adJgFlutterSplashAd = ADJgSplashAdLoadShowSeparate(
posId: KeyManager.splashPosid(), width: width, height: height);
// 加载广告
_adJgFlutterSplashAd!.load();
_adJgFlutterSplashAd!.onSucced = (AdInfo adInfo) {
print("开屏广告加载成功");
// 展示广告
_adJgFlutterSplashAd!.show();
};
_adJgFlutterSplashAd!.onFailed = (AdErrorInfo adErrorInfo) {
releaseSplashAd();
print("开屏广告加载失败");
toHome();
};
_adJgFlutterSplashAd!.onClicked = (AdInfo adInfo) {
print("开屏广告点击");
};
_adJgFlutterSplashAd!.onExposed = (AdInfo adInfo) {
print("开屏广告渲染成功");
};
_adJgFlutterSplashAd!.onClosed = (AdInfo adInfo) {
releaseSplashAd();
print("开屏广告关闭成功");
toHome();
};
}
return Scaffold(
body: Center(
child: (_adJgFlutterSplashAd == null
? Text("开屏广告已关闭")
: ADJgWidget(adView: _adJgFlutterSplashAd!))));
}
void toHome() {
Navigator.pushAndRemoveUntil(
context,
new MaterialPageRoute(builder: (context) => new MyApp()),
(route) => route == null,
);
}
void removeSplashAd() {
setState(() {
releaseSplashAd();
});
}
void releaseSplashAd() {
_adJgFlutterSplashAd?.release();
_adJgFlutterSplashAd = null;
}
@override
void dispose() {
releaseSplashAd();
super.dispose();
}
}
```
```dart
// 加载广告
_adJgFlutterSplashAd!.load();
```
```dart
// 展示广告(请在onSucced回调后使用,目前安卓端快手存在异常,请勿添加快手广告源)
_adJgFlutterSplashAd!.show();
```
## 4.3 横幅广告(banner)
```dart
class BannerPage extends StatefulWidget {
@override
State createState() => _BannerState();
}
class _BannerState extends State {
ADJgFlutterBannerAd _adJgFlutterBannerAd;
bool _hasInitBanner = false;
@override
Widget build(BuildContext context) {
if (_adJgFlutterBannerAd == null && _hasInitBanner == false) {
MediaQueryData queryData = MediaQuery.of(context);
_hasInitBanner = true;
var width = queryData.size.width;
var height = queryData.size.width / 320.0 * 50.0;
_adJgFlutterBannerAd = ADJgFlutterBannerAd(posId: KeyManager.bannerPosid(), width: width, height: height);
_adJgFlutterBannerAd.loadAndShow();
_adJgFlutterBannerAd.onSucced = (AdInfo adInfo) {
print("横幅广告加载成功");
};
_adJgFlutterBannerAd.onFailed = (AdErrorInfo adErrorInfo) {
removeBannerAd();
print("横幅广告加载失败");
};
_adJgFlutterBannerAd.onClicked = (AdInfo adInfo) {
print("横幅广告点击");
};
_adJgFlutterBannerAd.onExposed = (AdInfo adInfo) {
print("横幅广告渲染成功");
};
_adJgFlutterBannerAd.onClosed = (AdInfo adInfo) {
removeBannerAd();
print("横幅广告关闭成功");
};
}
return Scaffold(
appBar: AppBar(
title: Text("BannerPage"),
),
body: Center(child: (_adJgFlutterBannerAd == null ? Text("banner广告已关闭") : ADJgWidget(adView: _adJgFlutterBannerAd) ))
);
}
void removeBannerAd() {
setState(() {
releaseBannerAd();
});
}
void releaseBannerAd() {
_adJgFlutterBannerAd?.release();
_adJgFlutterBannerAd = null;
}
@override
void dispose() {
releaseBannerAd();
super.dispose();
}
}
```
## 4.4 插屏广告
```dart
class InterPage extends StatefulWidget {
@override
State createState() => _InterState();
}
class _InterState extends State {
ADJgIntertitialAd _interAd;
@override
Widget build(BuildContext context) {
showInterAd();
return Scaffold(
appBar: AppBar(
title: Text("Intertitial"),
),
body: Center(
),
);
}
// 插屏
// 显示插屏广告请保证当时app内没有其他地方显示插屏广告,否则会有冲突
void showInterAd() {
if(_interAd != null) {
return;
}
_interAd = ADJgIntertitialAd(posId: KeyManager.interPosid());
_interAd.onClicked = (AdInfo adInfo) {
print("插屏广告关闭了");
};
_interAd.onFailed = (AdErrorInfo adErrorInfo) {
print("插屏广告失败了");
releaseInterAd();
};
_interAd.onExposed = (AdInfo adInfo) {
print("插屏广告曝光了");
};
_interAd.onSucced = (AdInfo adInfo) {
print("插屏广告成功了");
playInterAd();
};
_interAd.onClicked = (AdInfo adInfo) {
print("插屏广告点击了");
};
_interAd.onRewarded = () {
print("插屏广告激励达成");
};
_interAd.onClosed = (AdInfo adInfo) {
print("插屏广告关闭");
releaseInterAd();
};
_interAd.load();
}
void releaseInterAd() {
_interAd?.release();
_interAd = null;
}
void playInterAd() {
_interAd.show();
}
@override
void dispose() {
releaseInterAd();
super.dispose();
}
}
```
## 4.5 信息流广告
```dart
class NativePage extends StatefulWidget {
@override
State createState() => NativeState();
}
class NativeState extends State {
ADJgFlutterNativeAd _nativeAd;
List _items = List.generate(10, (i) => i);
ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
_getAdData();
}
});
}
_getAdData() async {
_nativeAd.load();
}
void createNativeAd(BuildContext context) {
if(_nativeAd == null) {
MediaQueryData queryData = MediaQuery.of(context);
var width = queryData.size.width;
_nativeAd = ADJgFlutterNativeAd(posId: KeyManager.nativePosid(), width: width);
_nativeAd!.onFailed = (AdErrorInfo adErrorInfo) {
};
_nativeAd.onReceived = (ADJgFlutterNativeAdView adView) {
setState(() {
var adWidget = ADJgWidget(adView: adView);
adView.onClosed = (AdInfo adInfo) {
// 广告关闭回调
setState(() {
_items.remove(adWidget);
adView.release();
});
};
adView.onExposed = (AdInfo adInfo) {
// 广告曝光回调
};
adView.onClicked = (AdInfo adInfo) {
// 广告点击回调
};
_items.add(adWidget);
_items.addAll(List.generate(1, (i) => i));
});
};
}
}
@override
Widget build(BuildContext context) {
createNativeAd(context);
return Scaffold(
appBar: AppBar(
title: Text("Native"),
),
body: Center(
child: ListView.builder(
itemCount: _items.length,
controller: _scrollController,
itemBuilder: (BuildContext context, int index) {
final item = _items[index];
if (item is Widget) {
return item;
} else {
return Container(
width: 300,
height: 150,
child: Text("Cell", style: TextStyle(fontSize: 75))
);
}
}
),
),
);
}
@override
void dispose() {
for (var item in _items) {
if (item is ADJgFlutterNativeAdView) {
item.release();
}
}
_nativeAd.release();
_nativeAd = null;
super.dispose();
}
}
```
## 4.6 激励视频广告
```dart
class RewardPage extends StatefulWidget {
@override
State createState() => _RewardState();
}
class _RewardState extends State {
ADJgRewardAd _rewardAd;
@override
Widget build(BuildContext context) {
showRewardAd();
return Scaffold(
appBar: AppBar(
title: Text("Reward"),
),
body: Center(
),
);
}
void showRewardAd() {
if(_rewardAd != null) {
return;
}
_rewardAd = ADJgRewardAd(posId: KeyManager.rewardPosid());
// 服务端奖励回调配置,不对接可以不设置,部分渠道支持(优量汇、穿山甲、快手、百度)
_rewardAd!.setRewardValidationData(
RewardValidationData(
userId: "userId", // 用户id
custom: "custom", // 自定义参数
rewardName: "rewardName", // 奖励名称
rewardAmount: 1 // 奖励数量
)
);
_rewardAd.onFailed = (AdErrorInfo adErrorInfo) {
print("激励视频广告失败了");
releaseRewardAd();
};
_rewardAd.onExposed = (AdInfo adInfo) {
print("激励视频广告曝光了");
};
_rewardAd.onSucced = (AdInfo adInfo) {
print("激励视频广告成功了");
playRewardAd();
};
_rewardAd.onClicked = (AdInfo adInfo) {
print("激励视频广告点击了");
};
_rewardAd.onRewarded = (AdInfo adInfo) {
print("激励视频广告激励达成");
};
_rewardAd.onClosed = (AdInfo adInfo) {
print("激励视频广告关闭");
releaseRewardAd();
};
_rewardAd.load();
}
void releaseRewardAd() {
_rewardAd?.release();
_rewardAd = null;
}
void playRewardAd() {
_rewardAd.show();
}
@override
void dispose() {
releaseRewardAd();
super.dispose();
}
}
```
## 4.8 个性化化开关
```dart
AdJgFlutterSdk.setPersonalizedEnabled(personalized: true);
```
## 4.9 获取广告信息
目前onSucced、onClosed、onClicked、onExposed、onRewarded回调增加adInfo回传,开发者可通过以下方法获取广告信息
| 方法名 | 介绍 |
| ------------ | ---- |
| platformName | 获取三方广告平台名称,返回String类型。|
| ecpm | 获取ECPM,返回Double类型(单位:元)。|
| ecpmPrecision | ECPM类型,返回String类型(accurate:精准、platform_assignment:平台指定、estimate:估算)。|
## 5.0 获取广告错误信息
目前仅onFailed方法会回调,开发者可通过以下方法获取广告错误信息
| 方法名 | 介绍 |
| ------------ | ---- |
| errorCode | 错误码,返回int类型。|
| errorDescription | 获取错误信息,返回String类型。|