Flutter广告集成插件ad_klein_flutter_sdk的使用

Flutter广告集成插件ad_klein_flutter_sdk的使用

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

1.1 概述

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

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

2.1 SDK导入

首先需要导入主SDK:

dependencies:
  ad_klein_flutter_sdk: {library version}

然后需要导入各平台SDK,

2.1.1 iOS

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

pod 'AdKleinSDK/AdKleinSDKPlatforms/GDT'        # 优量汇(推荐)
pod 'AdKleinSDK/AdKleinSDKPlatforms/CSJ'        # 穿山甲(推荐)
pod 'AdKleinSDK/AdKleinSDKPlatforms/Mobius'     # 莫比乌斯(推荐)
#pod 'AdKleinSDK/AdKleinSDKPlatforms/BaiDu'      # 百青藤(可选)
#pod 'AdKleinSDK/AdKleinSDKPlatforms/Google'    # Admob(可选)
#pod 'AdKleinSDK/AdKleinSDKPlatforms/Smaato'    # Smaato(可选)

注意:接入Google的Admob广告请务必参考5.1.1在Info.plist中添加GADApplicationIdentifier信息。 iOS在pod install出现异常,删除掉podfileuse_frameworks!

2.1.2 Android

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

2.1.2.1 在android根目录build.gradle中添加klein仓库
allprojects {
    repositories {
        ...
        google()
        jcenter()
        mavenCentral()
        // 添加以下仓库地址
        // AdKlein远程仓库 credentials:访客模式
        maven {
                    credentials {
                        username '612da771fa25fa3e244cf7d8'
                        password '488L5cNZL50n'
                    }
                    url 'https://packages.aliyun.com/maven/repository/2133520-release-i5MW1M/'
                }
        // 如果添加了smaato广告,需要添加smaato的远程仓库依赖
        maven { url "https://s3.amazonaws.com/smaato-sdk-releases/" }
        // 如果添加了华为联盟广告,需要添加华为联盟的远程仓库依赖
        maven { url 'http://developer.huawei.com/repo/' }
    }
}
2.1.2.2 OAID支持

导入安全联盟的OAID支持库oaid_sdk_1.0.23.aar,可在Demo的libs目录下找到,强烈建议使用和Demo中一样版本的OAID库(包括项目中已存在的依赖的oaid版本); 将Demo中assets文件夹下的supplierconfig.json文件复制到自己的assets目录下并按照supplierconfig.json文件中的说明进行OAID的AppId配置,supplierconfig.json文件名不可修改;

2.1.2.3 添加AdKleinSDK和需要的AdapterSdk

将广告所需要的依赖集成进去,AdapterSdk可根据接入平台情况进行选择接入。

dependencies {
    // 至少接入一个平台,但不推荐全部接入。如果不清楚需要哪些平台可以咨询媒介。

    // OAID(必须)
    implementation(name: 'msa_mdid_1.0.23', ext: 'aar')

    // adKleinSdk(必须)
    implementation 'com.squareup.okhttp3:okhttp:3.12.1'
    implementation 'com.iusmob.adklein.ad:core:3.1.1'
    
    // 莫比乌斯,推荐接入(需要gson和okhttp支持)
    implementation 'com.iusmob.adklein.ad:mobius:2.1.3'
    implementation 'com.google.code.gson:gson:2.8.5'
    
    // 头条,推荐接入
    implementation 'com.iusmob.adklein.ad.adapter:toutiao:2.1.1'
    
    // 广点通,推荐接入
    implementation 'com.iusmob.adklein.ad.adapter:gdt:2.1.1'
    
    // 快手AdapterSDK,可选的
    implementation 'com.iusmob.adklein.ad.adapter:ks:2.1.1'
    
    // 百度AdapterSDK,可选的
    implementation 'com.iusmob.adklein.ad.adapter:baidu:2.1.1'
    
    // AdMobAdapterSdk,可选的(海外市场)
    implementation 'com.iusmob.adklein.ad.adapter:am:2.1.1'
    
    // SmMobAdapterSdk,可选的(海外市场)
    implementation 'com.iusmob.adklein.ad.adapter:sm:2.1.1'
    
    //华为AdapterSDK,可选的
    implementation 'com.iusmob.adklein.ad.adapter:hwpps:2.1.1'
    
    //米盟AdapterSDK,可选的(还需要gson和glide支持)
    implementation 'com.iusmob.adklein.ad.adapter:mimo:2.1.1'
}

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>taobao</string><!-- 淘宝  -->
  <string>tmall</string><!-- 天猫  -->
  <string>jdlogin</string><!-- 京东  -->
  <string>pinduoduo</string> <!-- 拼多多  -->
  <string>kaola</string> <!-- 网易考拉  -->
  <string>yanxuan</string> <!-- 网易严选  -->
  <string>vipshop</string> <!-- 唯品会  -->
  <string>suning</string> <!-- 苏宁  -->
  <string>mishopv1</string> <!-- 小米商城 -->
  <string>wireless1688</string> <!-- 阿里巴巴 -->

  <!-- 社交、社区-->
  <string>weibo</string><!-- 微博 -->
  <string>zhihu</string><!-- 知乎 -->
  <string>xhsdiscover</string><!-- 小红书 -->
  <string>momochat</string><!-- 陌陌 -->
  <string>blued</string><!-- blued -->
  <string>mqzone</string><!-- QQ空间 -->
  <string>mqq</string><!-- QQ -->
  <string>tantanapp</string><!-- 探探 -->
  <string>huputiyu</string><!-- 虎扑 -->
  <string>com.baidu.tieba</string> <!-- 贴吧  -->
  <string>tianya</string> <!-- 天涯社区  -->
  <string>douban</string> <!-- 豆瓣 -->
  <string>jike</string> <!-- 即刻 -->

  <!-- 短视频 -->
  <string>snssdk1128</string> <!-- 抖音 -->
  <string>snssdk1112</string> <!-- 火山 -->
  <string>snssdk32</string> <!-- 西瓜视频 -->
  <string>gifshow</string> <!-- 快手 -->

  <!-- 视频/直播 -->
  <string>tenvideo</string> <!-- 腾讯视频  -->
  <string>youku</string> <!-- 优酷  -->
  <string>bilibili</string> <!-- B站  -->
  <string>imgotv</string> <!-- 芒果TV  -->
  <string>qiyi-iphone</string> <!-- 爱奇艺  -->
  <string>hanju</string> <!-- 韩剧TV  -->
  <string>douyutv</string> <!-- 斗鱼  -->
  <string>yykiwi</string> <!-- 虎牙  -->

  <!-- 图片处理  -->
  <string>mtxx.open</string> <!-- 美图秀秀  -->
  <string>faceu</string> <!-- faceu国内  -->
  <string>ulike</string> <!-- 轻颜国内 -->

  <!-- 资讯 -->
  <string>snssdk141</string> <!-- 今日头条  -->
  <string>newsapp</string> <!-- 网易新闻  -->
  <string>qqnews</string> <!-- 腾讯新闻  -->
  <string>iting</string> <!-- 喜马拉雅 -->
  <string>weread</string> <!-- 微信读书 -->
  <string>jianshu</string> <!-- 简书 -->
  <string>igetApp</string> <!-- 得到 -->
  <string>kuaikan</string> <!-- 快看漫画 -->

  <!-- 财经 -->
  <string>sinanews</string> <!-- 新浪财经  -->
  <string>amihexin</string> <!-- 同花顺炒股 -->

  <!-- 音乐 -->
  <string>orpheus</string> <!-- 网易云音乐  -->
  <string>qqmusic</string> <!-- qq音乐  -->
  <string>kugouURL</string> <!-- 酷狗  -->
  <string>qmkege</string> <!-- 全民K歌 -->
  <string>changba</string> <!-- 唱吧  -->

  <!-- 工具 -->
  <string>iosamap</string> <!-- 高德地图  -->
  <string>baidumap</string> <!-- 百度地图   -->
  <string>baiduyun</string> <!-- 百度网盘  -->
  <string>rm434209233MojiWeather</string> <!-- 墨迹天气  -->

  <!-- 办公 -->
  <string>wxwork</string> <!-- 企业微信  -->
  <string>dingtalk</string> <!-- 钉钉 -->

  <!-- 生活 -->
  <string>imeituan</string> <!-- 美团  -->
  <string>dianping</string> <!-- 点评  -->
  <string>cainiao</string> <!-- 菜鸟裹裹  -->
  <string>wbmain</string> <!--  58同城 -->
  <string>mihome</string> <!--  米家 -->

  <!-- 美食佳饮  -->
  <string>xcfapp</string> <!-- 下厨房  -->
  <string>sbuxcn</string> <!-- 星巴克中国  -->
  <string>meituanwaimai</string> <!-- 美团外卖  -->

  <!-- 运动健康  -->
  <string>fb370547106731052</string> <!-- 小米运动  -->
  <string>meetyou.linggan</string> <!-- 美柚  -->
  <string>babytree</string> <!-- 宝宝树  -->
  <string>keep</string> <!-- keep  -->

  <!-- 旅行  -->
  <string>CtripWireless</string> <!-- 携程  -->
  <string>diditaxi</string> <!-- 滴滴  -->
  <string>taobaotravel</string> <!-- 飞猪  -->
  <string>travelguide</string> <!-- 马蜂窝  -->

  <!-- 游戏 -->
  <string>tencent1104466820</string> <!-- 王者荣耀  -->
  <string>tencent100689805</string> <!-- 天天爱消除  -->
  <string>tencent382</string> <!-- QQ斗地主  -->
</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/adklein_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/adklein_file_paths" />
</provider>

res/xml目录下(如果xml目录不存在需要手动创建),新建xml文件adklein_file_paths,在该文件中加入如下配置,如果存在相同android:authoritiesprovider,请将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 混淆配置

可以参考demoproguard-rules.pro相关配置

3.2 iOS14适配

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

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

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

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

弹窗小字文案建议:

<key>NSUserTrackingUsageDescription</key>
<string>获取标记权限向您提供更优质、安全的个性化服务及内容,未经同意我们不会用于其他目的;开启后,您也可以前往系统“设置-隐私 ”中随时关闭。</string>
3.2.1.2 向用户申请权限。
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>

- (void)requestIDFA {
  [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
    [self requestAd];
  }];
}

3.2.2 SKAdNetwork

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

3.2.2.1 将下列SKAdNetwork ID 添加到 info.plist 中,以保证 SKAdNetwork 的正确运行。根据对接平台添加相应SKAdNetworkID,若无对接平台SKNetworkID则无需添加。
<key>SKAdNetworkItems</key>
<array>
<!-- 穿山甲  -->
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>238da6jt44.skadnetwork</string>
  </dict>
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>x2jnk7ly8j.skadnetwork</string>
  </dict>
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>22mmun2rn5.skadnetwork</string>
  </dict>
  <!-- 优量汇(广点通)  -->
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>f7s53z58qe.skadnetwork</string>
  </dict>
  <!-- Admob(谷歌广告)) -->
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>cstr6suwn9.skadnetwork</string>
  </dict>
</array>

4.1 主SDK初始化

AdKleinFlutterSdk.initSdk(appid: "appid");

4.2 开屏广告

class SplashPage extends StatefulWidget {
  [@override](/user/override)
  State<StatefulWidget> createState() => _SplashState();
}

class _SplashState extends State<SplashPage> {
  var _splashAd;

  [@override](/user/override)
  Widget build(BuildContext context) {
    showSplashAd();
    return Scaffold(
      appBar: AppBar(
        title: Text("Splash"),
      ),
      body: Center(),
    );
  }

  // 开屏
  // 显示开屏广告请保证当时app内没有其他地方显示开屏广告,否则会有冲突
  void showSplashAd() {
    if (_splashAd != null) {
      return;
    }
    _splashAd = ADKleinSplashAd(Constants.splashPosid(), "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](/user/override)
  void dispose() {
    releaseSplashAd();
    super.dispose();
  }
}

4.3 横幅广告(banner)

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

class _BannerState extends State<BannerPage> {
  var _adKleinFlutterBannerAd;
  bool _hasInitBanner = false;

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

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

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

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

  [@override](/user/override)
  void dispose() {
    releaseBannerAd();
    super.dispose();
  }
}

4.4 全屏视频广告

class FullScreenPage extends StatefulWidget {
  [@override](/user/override)
  State<StatefulWidget> createState() => FullScreenState();
}

class FullScreenState extends State<FullScreenPage> {
  var _fullScreenVodAd;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FullScreenVodAd"),
      ),
      body: Center(
        child: Column(
          children: [
            TextButton(
              onPressed: () {
                showFullScreenVodAd();
              },
              child: Text("加载广告"),
            ),
          ],
        ),
      ),
    );
  }

  // 全屏视频
  // 显示全屏视频广告请保证当时app内没有其他地方显示全屏视频广告,否则会有冲突
  void showFullScreenVodAd() {
    if (_fullScreenVodAd != null) {
      return;
    }
    _fullScreenVodAd =
        ADKleinFullScreenVodAd(posId: Constants.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](/user/override)
  void dispose() {
    releaseFullScreenVodAd();
    super.dispose();
  }
}

4.5 插屏广告

class InterPage extends StatefulWidget {
  [@override](/user/override)
  State<StatefulWidget> createState() => _InterState();
}

class _InterState extends State<InterPage> {
  var _interAd;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Intertitial"),
      ),
      body: Center(
        child: Column(
          children: [
            TextButton(
              onPressed: () {
                showInterAd();
              },
              child: Text("加载广告"),
            ),
          ],
        ),
      ),
    );
  }

  // 插屏
  // 显示插屏广告请保证当时app内没有其他地方显示插屏广告,否则会有冲突
  void showInterAd() {
    if (_interAd != null) {
      return;
    }
    _interAd = ADKleinIntertitialAd(posId: Constants.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](/user/override)
  void dispose() {
    releaseInterAd();
    super.dispose();
  }
}

4.6 信息流广告

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

class NativeState extends State<NativePage> {
  var _nativeAd;

  List<dynamic> _items = List.generate(10, (i) => i);
  ScrollController _scrollController = ScrollController();

  [@override](/user/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 =
          ADKleinFlutterNativeAd(posId: Constants.nativePosid(), width: width);
      _nativeAd.onReceived = (ADKleinFlutterNativeAdView adView) {
        setState(() {
          var adWidget = ADKleinWidget(adView: adView);
          adView.onClosed = () {
            setState(() {
              _items.remove(adWidget);
              adView.release();
            });
          };
          adView.onExposed = () {};

          _items.add(adWidget);
          _items.addAll(List.generate(1, (i) => i));
        });
      };
    }
  }

  [@override](/user/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](/user/override)
  void dispose() {
    for (var item in _items) {
      if (item is ADKleinFlutterNativeAdView) {
        item.release();
      }
    }
    _nativeAd.release();
    _nativeAd = null;
    super.dispose();
  }
}

4.7 激励视频广告

class RewardPage extends StatefulWidget {
  [@override](/user/override)
  State<StatefulWidget> createState() => _RewardState();
}

class _RewardState extends State<RewardPage> {
  var _rewardAd;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Reward"),
      ),
      body: Center(
        child: Column(
          children: [
            TextButton(
              onPressed: () {
                showRewardAd();
              },
              child: Text("加载广告"),
            ),
          ],
        ),
      ),
    );
  }

  void showRewardAd() {
    if (_rewardAd != null) {
      return;
    }
    _rewardAd = ADKleinRewardAd(posId: Constants.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](/user/override)
  void dispose() {
    releaseRewardAd();
    super.dispose();
  }
}

示例代码

import 'package:ad_klein_flutter_sdk/ad_klein_flutter_sdk.dart';
import 'package:flutter/material.dart';

import 'Constants.dart';
import 'banner.dart';
import 'fullscreen.dart';
import 'inter.dart';
import 'native.dart';
import 'reward.dart';
import 'splash.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
    AdKleinFlutterSdk.initSdk(appid: Constants.appKey());
  }

  static const listData = [
    "SplashAd(开屏广告)",
    "Native(信息流广告)",
    "Banner(横幅广告)",
    "Inter(插屏广告)",
    "Reward(激励视频广告)",
    "fullscreenVod(全屏视频广告)"
  ];

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: const Text('ADKlein广告Demo_Flutter'),
          ),
          body: ListView.builder(
            itemCount: listData.length,
            padding: const EdgeInsets.all(15),
            itemBuilder: (BuildContext context, int index) {
              return Container(
                  margin: EdgeInsets.symmetric(vertical: 10),
                  decoration: new BoxDecoration(
                    border: new Border.all(
                      width: 1,
                      color: Colors.blue,
                    ),
                    borderRadius: BorderRadius.all(Radius.circular(4.0)),
                  ),
                  child: GestureDetector(
                    behavior: HitTestBehavior.opaque,
                    onTap: () {
                      var widget;
                      switch (index) {
                        case 0:
                          widget = SplashPage();
                          break;
                        case 1:
                          widget = NativePage();
                          break;
                        case 2:
                          widget = BannerPage();
                          break;
                        case 3:
                          widget = InterPage();
                          break;
                        case 4:
                          widget = RewardPage();
                          break;
                        case 5:
                          widget = FullScreenPage();
                          break;
                      }
                      Navigator.push(context,
                          MaterialPageRoute(builder: (context) {
                        return widget;
                      }));
                    },
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const SizedBox(height: 10),
                        Text(listData[index], textAlign: TextAlign.center),
                        const SizedBox(height: 10),
                      ],
                    ),
                  ));
            },
          )),
    );
  }
}

更多关于Flutter广告集成插件ad_klein_flutter_sdk的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter广告集成插件ad_klein_flutter_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


ad_klein_flutter_sdk 是一个用于在 Flutter 应用中集成广告的插件,通常用于展示横幅广告、插屏广告、激励视频广告等。以下是如何使用 ad_klein_flutter_sdk 的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 ad_klein_flutter_sdk 的依赖。

dependencies:
  flutter:
    sdk: flutter
  ad_klein_flutter_sdk: ^版本号 # 请替换为最新的版本号

然后运行 flutter pub get 来获取依赖。

2. 初始化 SDK

在使用广告之前,你需要初始化 ad_klein_flutter_sdk。通常在 main.dart 文件中进行初始化。

import 'package:ad_klein_flutter_sdk/ad_klein_flutter_sdk.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  AdKleinFlutterSdk.init(appId: '你的AppID'); // 替换为你的AppID
  runApp(MyApp());
}

3. 展示横幅广告

横幅广告是一种常见的广告形式,通常在应用界面的顶部或底部展示。

import 'package:flutter/material.dart';
import 'package:ad_klein_flutter_sdk/ad_klein_flutter_sdk.dart';

class BannerAdExample extends StatefulWidget {
  [@override](/user/override)
  _BannerAdExampleState createState() => _BannerAdExampleState();
}

class _BannerAdExampleState extends State<BannerAdExample> {
  AdKleinBannerAd? _bannerAd;

  [@override](/user/override)
  void initState() {
    super.initState();
    _loadBannerAd();
  }

  void _loadBannerAd() {
    _bannerAd = AdKleinBannerAd(
      adUnitId: '你的Banner广告位ID', // 替换为你的Banner广告位ID
      adSize: AdSize.banner,
      listener: AdKleinBannerAdListener(
        onAdLoaded: (Ad ad) {
          print('Banner Ad loaded.');
        },
        onAdFailedToLoad: (Ad ad, AdError error) {
          print('Banner Ad failed to load: $error');
        },
      ),
    )..load();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Banner Ad Example'),
      ),
      body: Center(
        child: _bannerAd != null
            ? AdWidget(ad: _bannerAd!)
            : Text('Loading Banner Ad...'),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    _bannerAd?.dispose();
    super.dispose();
  }
}

4. 展示插屏广告

插屏广告是一种全屏广告,通常在用户完成某个操作后展示。

import 'package:flutter/material.dart';
import 'package:ad_klein_flutter_sdk/ad_klein_flutter_sdk.dart';

class InterstitialAdExample extends StatefulWidget {
  [@override](/user/override)
  _InterstitialAdExampleState createState() => _InterstitialAdExampleState();
}

class _InterstitialAdExampleState extends State<InterstitialAdExample> {
  AdKleinInterstitialAd? _interstitialAd;

  [@override](/user/override)
  void initState() {
    super.initState();
    _loadInterstitialAd();
  }

  void _loadInterstitialAd() {
    AdKleinInterstitialAd.load(
      adUnitId: '你的插屏广告位ID', // 替换为你的插屏广告位ID
      request: AdRequest(),
      adLoadCallback: AdKleinInterstitialAdLoadCallback(
        onAdLoaded: (AdKleinInterstitialAd ad) {
          _interstitialAd = ad;
          _interstitialAd?.show();
        },
        onAdFailedToLoad: (AdError error) {
          print('Interstitial Ad failed to load: $error');
        },
      ),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Interstitial Ad Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _loadInterstitialAd,
          child: Text('Show Interstitial Ad'),
        ),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    _interstitialAd?.dispose();
    super.dispose();
  }
}

5. 展示激励视频广告

激励视频广告是一种用户可以选择观看以获取奖励的广告形式。

import 'package:flutter/material.dart';
import 'package:ad_klein_flutter_sdk/ad_klein_flutter_sdk.dart';

class RewardedAdExample extends StatefulWidget {
  [@override](/user/override)
  _RewardedAdExampleState createState() => _RewardedAdExampleState();
}

class _RewardedAdExampleState extends State<RewardedAdExample> {
  AdKleinRewardedAd? _rewardedAd;

  [@override](/user/override)
  void initState() {
    super.initState();
    _loadRewardedAd();
  }

  void _loadRewardedAd() {
    AdKleinRewardedAd.load(
      adUnitId: '你的激励视频广告位ID', // 替换为你的激励视频广告位ID
      request: AdRequest(),
      adLoadCallback: AdKleinRewardedAdLoadCallback(
        onAdLoaded: (AdKleinRewardedAd ad) {
          _rewardedAd = ad;
          _rewardedAd?.show();
        },
        onAdFailedToLoad: (AdError error) {
          print('Rewarded Ad failed to load: $error');
        },
      ),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Rewarded Ad Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _loadRewardedAd,
          child: Text('Show Rewarded Ad'),
        ),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    _rewardedAd?.dispose();
    super.dispose();
  }
}
回到顶部