ad_suyi_flutter_sdk

TOC

1.1 概述

尊敬的开发者朋友,欢迎您使用ADmobile 苏伊士广告SDK。通过本文档,您可以在几分钟之内轻松完成广告的集成过程。

操作系统: iOS 9.0 及以上版本,Android 4.4 及以上版本,

运行设备:iPhone (iPad上可能部分广告正常展示,但是存在填充很低或者平台不支持等问题,建议不要在iPad上展示广告),Android

2.1 SDK导入

首先需要导入主SDK

dependencies:
  ad_suyi_flutter_sdk: {library version}

然后需要导入各平台SDK,

2.1.1 iOS在项目的podfile中增加如下内容,可以根据实际需要选择性导入平台

pod 'ADSuyiSDK/ADSuyiSDKPlatforms/gdt'     	# 优量汇
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/admobile' # ADMobile  #必选
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/baidu'		# baidu
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/bu'   		# 穿山甲(头条)
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/google'   # 谷歌
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/inmobi'   # Inmobi
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/ks'				# 快手
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/unity'		# Unity
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/mtg'			# Mobvista(汇量)
pod 'ADSuyiSDK/ADSuyiSDKPlatforms/vungle'		# vungle
// 推荐导入,通过系统定位获取定位信息
pod 'ADSuyiLocationManagerGPS'// 含有系统定位代码

2.1.2 Android在项目中增加如下内容,可以根据实际需要选择性导入平台

2.1.2.1. 在android根目录build.gradle中添加suyi仓库

allprojects {
    repositories {
        ...
        google()
        jcenter()
        mavenCentral()
        // ADSuyi远程仓库
        maven { url "http://101.37.191.20:9091/repository/maven-releases/" }
        // 如果添加了汇量广告,需要添加汇量的远程仓库依赖
        maven { url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_support/" }
        // 如果添加了云码广告,需要添加云码的远程仓库依赖
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/releases/' }
        // 如果添加了华为联盟广告,需要添加华为联盟的远程仓库依赖
        maven { url 'https://developer.huawei.com/repo/' }
    }
}

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中添加相关依赖

// support支持库,如果是AndroidX请使用对应的支持库
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:design:28.0.0'

implementation 'cn.admobiletop.adsuyi.ad:core:3.2.3.06172'
// common库是必须导入的,请保持和Demo中版本一致
implementation 'com.admobile:common:1.2.8'
// material库是必须导入的,请保持和Demo中版本一致
implementation 'cn.admobiletop.adsuyi.ad:material:1.0.2.05111'

// OAID库是必须导入的,请保持和Demo中版本一致(如果当前Suyi是3.0.9及以上版本,
// 必须保证oaid版本为oaid_sdk_1.0.25,oaid_sdk_1.0.25为msa_mdid_1.0.13、oaid_sdk_1.0.23的升级版,请删除原有的msa_mdid)
implementation(name: 'oaid_sdk_1.0.25', ext: 'aar')

// 艾狄墨搏AdapterSdk,必须的`
implementation 'cn.admobiletop.adsuyi.ad.adapter:admobile:4.9.6.07121'

// 广点通AdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:gdt:4.371.1241.06281'

// 头条AdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:toutiao:3.8.0.0.06231'

// 百度AdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:baidu:5.98.05131'

// 汇量AdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:mintegral:15.5.27.06012'

// InmobiAdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:inmobi:7.5.1.11112'
implementation 'com.squareup.picasso:picasso:2.5.2'

// 讯飞AdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:ifly:5.0.2.06011'

/ 快手基础版AdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:ksadbase:3.3.10.2.06181'

// 快手内容版AdapterSdk,可选的(比快手基础版多一个内容组件,不需要内容组件无需导入该版本,不可和快手基础版同时导入)
implementation 'cn.admobiletop.adsuyi.ad.adapter:ksadcontent:3.3.18.1.06181'

// 米盟AdapterSdk,可选的(还需要gson和glide支持)
implementation 'cn.admobiletop.adsuyi.ad.adapter:mimo:5.0.6.11263'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'

// 华为广告联盟AdadapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:hwpps:13.4.45.302.06281'

// 云码AdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:yunma:1.0.3.04211'

// 爱奇艺AdapterSdk,可选的
implementation 'cn.admobiletop.adsuyi.ad.adapter:iqy:1.3.11.06181'

3.1 工程环境配置

3.1.1 IOS 工程环境配置

3.1.1.1. info.plist 添加支持 Http访问字段

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

3.1.1.2. Info.plist 添加定位权限字段(使用ADMobGenLocation可不设置)

NSLocationWhenInUseUsageDescription
NSLocationAlwaysAndWhenInUseUsageDeion

3.1.1.3. Info.plist推荐设置白名单,可提高广告收益

<key>LSApplicationQueriesSchemes</key>
    <array>
        <string>dianping</string>
        <string>imeituan</string>
        <string>com.suning.SuningEBuy</string>
        <string>openapp.jdmobile</string>
        <string>vipshop</string>
        <string>snssdk141</string>
        <string>ctrip</string>
        <string>suning</string>
        <string>qunariphone</string>
        <string>QunarAlipay</string>
        <string>qunaraphone</string>
        <string>yohobuy</string>
        <string>kaola</string>
        <string>agoda</string>
        <string>openapp.xzdz</string>
        <string>beibeiapp</string>
        <string>taobao</string>
        <string>tmall</string>
        <string>openjd</string>
        <string>jhs</string>
        <string>yhd</string>
        <string>wireless1688</string>
        <string>GomeEShop</string>
        <string>wbmain</string>
        <string>xhsdiscover</string>
        <string>douyin</string>
        <string>pinduoduo</string>
        <string>jdmobile</string>
        <string>tbopen</string>
        <string>pddopen</string>
        <string>mogujie</string>
        <string>koubei</string>
        <string>eleme</string>
        <string>youku</string>
        <string>gengmei</string>
        <string>airbnb</string>
        <string>alipays</string>
        <string>didicommon</string>
        <string>OneTravel</string>
        <string>farfetchCN</string>
        <string>farfetch</string>
        <string>snssdk1112</string>
        <string>snssdk1128</string>
        <string>miguvideo</string>
        <string>kfcapplinkurl</string>
        <string>iqiyi</string>
        <string>uclink</string>
        <string>app.soyoung</string>
    </array>

3.1.2 Android 工程环境配置

3.1.2.1 权限配置

<!-- 广告必须的权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

<!-- 广点通广告必须的权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 影响广告填充,强烈建议的权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<!-- 为了提高广告收益,建议设置的权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<!-- 如果有视频相关的广告播放请务必添加-->
<uses-permission android:name="android.permission.WAKE_LOCK" />

3.1.2.2 FileProvider配置

适配Anroid7.0以及以上,请在AndroidManifest中添加如下代码: 如果支持库是support

<provider
	  android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
    		android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/adsuyi_file_paths" />
</provider>

如果支持库为androidx

<provider
	  android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
    		android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/adsuyi_file_paths" />
</provider>

在res/xml目录下(如果xml目录不存在需要手动创建),新建xml文件adsuyi_file_paths,在该文件中加入如下配置,如果存在相同android:authorities的provider,请将paths标签中的路劲配置到自己的xml文件中:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_path" path="." />
    <external-files-path name="external_files_path" path="." />
</paths>

3.1.2.3 网络配置

需要在 AndroidManifest.xml 添加依赖声明uses-library android:name="org.apache.http.legacy" android:required="false", 且 application标签中添加 android:usesCleartextTraffic="true",适配网络http请求,否则 SDK可能无法正常工作,接入代码示例如下:

<application
    android:name=".MyApplication"
        ... ...
    android:usesCleartextTraffic="true">

    <uses-library
        android:name="org.apache.http.legacy"
        android:required="false" />
    ... ...
</application>

3.1.2.4 混淆配置

可以参考demo中proguard-rules.pro相关配置

3.2 iOS14适配

由于iOS14中对于权限和隐私内容有一定程度的修改,而且和广告业务关系较大,请按照如下步骤适配,如果未适配。不会导致运行异常或者崩溃等情况,但是会一定程度上影响广告收入。敬请知悉。

  1. 应用编译环境升级至 Xcode 12.0 及以上版本;
  2. 升级ADSuyiSDK 3.0.8及以上版本;
  3. 设置SKAdNetwork和IDFA权限;

3.2.1 获取App Tracking Transparency授权(弹窗授权获取IDFA)

从 iOS 14 开始,在应用程序调用 App Tracking Transparency 向用户提跟踪授权请求之前,IDFA 将不可用。

  1. 更新 Info.plist,添加 NSUserTrackingUsageDescription 字段和自定义文案描述。

    弹窗小字文案建议:

    • 获取标记权限向您提供更优质、安全的个性化服务及内容,未经同意我们不会用于其他目的;开启后,您也可以前往系统“设置-隐私 ”中随时关闭。
    • 获取IDFA标记权限向您提供更优质、安全的个性化服务及内容;开启后,您也可以前往系统“设置-隐私 ”中随时关闭。
<key>NSUserTrackingUsageDescription</key>
<string>获取标记权限向您提供更优质、安全的个性化服务及内容,未经同意我们不会用于其他目的;开启后,您也可以前往系统“设置-隐私 ”中随时关闭</string>
  1. 向用户申请权限。
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>
...
- (void)requestIDFA {
  [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
    // 无需对授权状态进行处理
  }];
}
// 建议启动App就获取权限或者请求广告前获取
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  	[self requestIDFA];
}

3.2.2 SKAdNetwork

SKAdNetwork 是接收iOS端营销推广活动归因数据的一种方法。

  1. 将下列SKAdNetwork ID 添加到 info.plist 中,以保证 SKAdNetwork 的正确运行。根据对接平台添加相应SKAdNetworkID,若无对接平台SKNetworkID则无需添加。
<key>SKAdNetworkItems</key>
  <array>
    // 穿山甲广告(ADSuyiBU)
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>238da6jt44.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>22mmun2rn5.skadnetwork</string>
    </dict>
    // 谷歌广告(ADSuyiGoogle)
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>cstr6suwn9.skadnetwork</string>
    </dict>
    // Unity广告(ADSuyiUnity)
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>4DZT52R2T5.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>bvpn9ufa9b.skadnetwork</string>
    </dict>
    // 汇量广告(ADSuyiMTG)
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>KBD757YWX3.skadnetwork</string>
    </dict>
    // 汇量广告 合作伙伴(ADSuyiMTG)
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>wg4vff78zm.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>737z793b9f.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>ydx93a7ass.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>prcb7njmu6.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>7UG5ZH24HU.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>44jx6755aq.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>2U9PT9HC89.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>W9Q455WK68.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>YCLNXRL5PM.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>TL55SBB4FM.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>8s468mfl3y.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>GLQZH8VGBY.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>c6k4g5qg8m.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>mlmmfzh3r3.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>4PFYVQ9L8R.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>av6w8kgt66.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>6xzpu9s2p8.skadnetwork</string>
    </dict>
    <dict>
        <key>SKAdNetworkIdentifier</key>
        <string>hs6bdukanm.skadnetwork</string>
    </dict>
  </array>

4.1 主SDK初始化

AdSuyiFlutterSdk.initSdk(appid: "appid");

4.2 开屏广告

class SplashPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SplashState(); 
}
class _SplashState extends State<SplashPage> {
  ADSuyiSplashAd _splashAd;
  @override
  Widget build(BuildContext context) {
    showSplashAd();
    return Scaffold(
      appBar: AppBar(
        title: Text("Splash"),
      ),
      body: Center(
      ),
    );
  }
  // 开屏
  // 显示开屏广告请保证当时app内没有其他地方显示开屏广告,否则会有冲突
  void showSplashAd() {
    if(_splashAd != null) {
      return;
    }
    _splashAd = ADSuyiSplashAd(posId: "posid", imgName: "splash_placeholder");
    _splashAd.onClosed = () {
      print("开屏广告关闭了");
      // 在加载失败和关闭回调后关闭广告
      releaseSplashAd();
    };
    _splashAd.onFailed = () {
      print("开屏广告失败了");
      // 在加载失败和关闭回调后关闭广告
      releaseSplashAd();
    };
    _splashAd.onExposed = () { print("开屏广告曝光了"); };
    _splashAd.onSucced = () { print("开屏广告成功了"); };
    _splashAd.onClicked = () { print("开屏广告点击了"); };
    _splashAd.loadAndShow();
  }

  void releaseSplashAd() {
    _splashAd?.release();
    _splashAd = null;
  }

  @override
  void dispose() {
    releaseSplashAd();
    super.dispose();
  }
}

4.3 横幅广告(banner)

class BannerPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _BannerState();
}

class _BannerState extends State<BannerPage> {
  ADSuyiFlutterBannerAd _adSuyiFlutterBannerAd;
  bool _hasInitBanner = false;

  @override
  Widget build(BuildContext context) {
    if (_adSuyiFlutterBannerAd == null && _hasInitBanner == false) {
      MediaQueryData queryData = MediaQuery.of(context);
      _hasInitBanner = true;
      var width = queryData.size.width;
      var height = queryData.size.width / 320.0 * 50.0;
      _adSuyiFlutterBannerAd = ADSuyiFlutterBannerAd(posId: KeyManager.bannerPosid(), width: width, height: height);
      _adSuyiFlutterBannerAd.loadAndShow();
      _adSuyiFlutterBannerAd.onSucced = () {
        print("横幅广告加载成功");
      };
      _adSuyiFlutterBannerAd.onFailed = () {
        removeBannerAd();
        print("横幅广告加载失败");
      };
      _adSuyiFlutterBannerAd.onClicked = () {
        print("横幅广告点击");
      };
      _adSuyiFlutterBannerAd.onExposed = () {
        print("横幅广告渲染成功");
      };
      _adSuyiFlutterBannerAd.onClosed = () {
        removeBannerAd();
        print("横幅广告关闭成功");
      };
    }

    return Scaffold(
        appBar: AppBar(
          title: Text("BannerPage"),
        ),
        body: Center(child: (_adSuyiFlutterBannerAd == null ? Text("banner广告已关闭") : ADSuyiWidget(adView: _adSuyiFlutterBannerAd) ))
    );
  }

  void removeBannerAd() {
    setState(() {
      releaseBannerAd();
    });
  }

  void releaseBannerAd() {
    _adSuyiFlutterBannerAd?.release();
    _adSuyiFlutterBannerAd = null;
  }

  @override
  void dispose() {
    releaseBannerAd();
    super.dispose();
  }
}

4.4 全屏视频广告

class FullScreenPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => FullScreenState();
}
class FullScreenState extends State<FullScreenPage> {
  ADSuyiFullScreenVodAd _fullScreenVodAd;
  @override
  Widget build(BuildContext context) {
    showFullScreenVodAd();
    return Scaffold(
      appBar: AppBar(
        title: Text("FullScreenVodAd"),
      ),
      body: Center(
      ),
    );
  }
  // 全屏视频
  // 显示全屏视频广告请保证当时app内没有其他地方显示全屏视频广告,否则会有冲突
  void showFullScreenVodAd() {
    if(_fullScreenVodAd != null) {
      return;
    }
    _fullScreenVodAd = ADSuyiFullScreenVodAd(posId: KeyManager.fullScreenPosid());
    _fullScreenVodAd.onClicked = () {
      print("全屏视频广告关闭了");
    };
    _fullScreenVodAd.onFailed = () {
      print("全屏视频广告失败了");
      releaseFullScreenVodAd();
    };
    _fullScreenVodAd.onExposed = () {
      print("全屏视频广告曝光了");
    };
    _fullScreenVodAd.onSucced = () {
      print("全屏视频广告成功了");
      playFullScreenVodAd();
    };
    _fullScreenVodAd.onClicked = () {
      print("全屏视频广告点击了");
    };
    _fullScreenVodAd.onRewarded = () {
      print("全屏视频广告激励达成");
    };
    _fullScreenVodAd.onClosed = () {
      print("全屏视频广告关闭");
      releaseFullScreenVodAd();
    };
    _fullScreenVodAd.load();
  }
  void releaseFullScreenVodAd() {
    _fullScreenVodAd?.release();
    _fullScreenVodAd = null;
  }
  void playFullScreenVodAd() {
    _fullScreenVodAd.show();
  }
  @override
  void dispose() {
    releaseFullScreenVodAd();
    super.dispose();
  }
}

4.5 插屏广告

class InterPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _InterState();
}
class _InterState extends State<InterPage> {
  ADSuyiIntertitialAd _interAd;
  @override
  Widget build(BuildContext context) {
    showInterAd();
    return Scaffold(
      appBar: AppBar(
        title: Text("Intertitial"),
      ),
      body: Center(
      ),
    );
  }
  // 插屏
  // 显示插屏广告请保证当时app内没有其他地方显示插屏广告,否则会有冲突
  void showInterAd() {
    if(_interAd != null) {
      return;
    }
    _interAd = ADSuyiIntertitialAd(posId: KeyManager.interPosid());
    _interAd.onClicked = () {
      print("插屏广告关闭了");
    };
    _interAd.onFailed = () {
      print("插屏广告失败了");
      releaseInterAd();
    };
    _interAd.onExposed = () {
      print("插屏广告曝光了");
    };
    _interAd.onSucced = () {
      print("插屏广告成功了");
      playInterAd();
    };
    _interAd.onClicked = () {
      print("插屏广告点击了");
    };
    _interAd.onRewarded = () {
      print("插屏广告激励达成");
    };
    _interAd.onClosed = () {
      print("插屏广告关闭");
      releaseInterAd();
    };
    _interAd.load();
  }
  void releaseInterAd() {
    _interAd?.release();
    _interAd = null;
  }
  void playInterAd() {
    _interAd.show();
  }
  @override
  void dispose() {
    releaseInterAd();
    super.dispose();
  }
}

4.6 信息流广告

class NativePage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => NativeState();
}

class NativeState extends State<NativePage> {

  ADSuyiFlutterNativeAd _nativeAd;

  List<dynamic> _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 = ADSuyiFlutterNativeAd(posId: KeyManager.nativePosid(), width: width);
      _nativeAd.onReceived = (ADSuyiFlutterNativeAdView adView) {
        setState(() {
          var adWidget = ADSuyiWidget(adView: adView);
          adView.onClosed = () {
            setState(() {
              _items.remove(adWidget);
              adView.release();
            });
          };
          adView.onExposed = () {

          };

          _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 ADSuyiFlutterNativeAdView) {
        item.release();
      }
    }
    _nativeAd.release();
    _nativeAd = null;
    super.dispose();
  }
}

4.7 激励视频广告

class RewardPage extends StatefulWidget {
  
  @override
  State<StatefulWidget> createState() => _RewardState();

}
class _RewardState extends State<RewardPage> {

  ADSuyiRewardAd _rewardAd;

  @override
  Widget build(BuildContext context) {
    showRewardAd();
    return Scaffold(
      appBar: AppBar(
        title: Text("Reward"),
      ),
      body: Center(
      ),
    );
  }

  void showRewardAd() {
    if(_rewardAd != null) {
      return;
    }
    _rewardAd = ADSuyiRewardAd(posId: KeyManager.rewardPosid());
    _rewardAd.onClicked = () {
      print("激励视频广告关闭了");
    };
    _rewardAd.onFailed = () {
      print("激励视频广告失败了");
      releaseRewardAd();
    };
    _rewardAd.onExposed = () {
      print("激励视频广告曝光了");
    };
    _rewardAd.onSucced = () {
      print("激励视频广告成功了");
      playRewardAd();
    };
    _rewardAd.onClicked = () {
      print("激励视频广告点击了");
    };
    _rewardAd.onRewarded = () {
      print("激励视频广告激励达成");
    };
    _rewardAd.onClosed = () {
      print("激励视频广告关闭");
      releaseRewardAd();
    };
    _rewardAd.load();
  }

  void releaseRewardAd() {
    _rewardAd?.release();
    _rewardAd = null;
  }

  void playRewardAd() {
    _rewardAd.show();
  }

  @override
  void dispose() {
    releaseRewardAd();
    super.dispose();
  }
}

Libraries

ad_suyi_ad
ad_suyi_base
ad_suyi_flutter_sdk