IPD_Android_Flutter_Plugin

IPDSDK Android 平台 flutter 插件

支持的广告及类型

  • 开屏广告原生展示
  • 开屏广告Widget
  • 激励视频
  • 插屏广告
  • 全屏广告
  • 横幅广告
  • 信息流广告
  • 视频流广告
  • 视频内容
  • 新闻资讯
  • H5页面

开始接入

插件需要Flutter >=3.0.0,请升级Flutter版本 enhanced Enum需要指定SDK>=2.17.0,请调整SDK版本 SDK版本调整后依然报错,请手动删除.dart_tool目录重新执行pub-get

environment:
  sdk: ">=2.17.0 <3.0.0"

引入依赖

  1. 参照example,在pubspec中引入ipdsdk_android插件,并指定插件路径:
dependencies:
  #...

  ipdsdk_android:
    path: ../

  #...

**注意:**如使用example中的测试ID调试时,需要修改build.gradleandroid->defaultConfig->applicationId"com.zjcj.hwzs.addemo"。广告ID与包名是绑定关系,使用其他包名会导致广告请求失败。

初始化SDK

个性化推荐、程序化推荐配置

SDK提供了个性化推荐、程序化推荐配置开关,仅需在状态发生改变时调用,可在初始化方法调用之前配置。

class IPDAndroid {
  /// 配置个性化推荐开关
  /// [state] 是否开启推荐
  static void setPersonalRecommend(bool state);

  /// 配置程序化推荐开关
  /// [state] 是否开启推荐
  static void setProgrammaticRecommend(bool state);
}

隐私权限控制

SDK提供了隐私权限控制配置,需要在每次初始化时传入:

/// 隐私权限控制
class IPDCustomController {
  static const List<String> defaultInstalledPackages = [];

  /// 主动获取定位
  final bool canReadLocation;

  /// 经度
  final double longitude;

  /// 纬度
  final double latitude;

  /// 主动获取设备信息
  final bool canUsePhoneState;

  /// IMEI
  final String imei;

  /// 主动获取AndroidID
  final bool canUseAndroidId;

  /// AndroidID
  final String androidId;

  /// 主动获取MAC地址
  final bool canUseMacAddress;

  /// MAC地址
  final String macAddress;

  /// 主动获取OAID
  final bool canUseOaid;

  /// OAID/GAID
  final String oaid;

  /// 获取网络状态
  final bool canUseNetworkState;

  /// 使用存储
  final bool canUseStoragePermission;

  /// 主动读取已安装应用列表
  final bool canReadInstalledPackages;

  /// 已安装应用列表
  final List<String> installedPackages;

  IPDCustomController({this.canReadLocation = true,
    this.longitude = 0.0000,
    this.latitude = 0.0000,
    this.canUsePhoneState = true,
    this.imei = "",
    this.canUseAndroidId = true,
    this.androidId = "",
    this.canUseMacAddress = true,
    this.macAddress = "",
    this.canUseOaid = true,
    this.oaid = "",
    this.canUseNetworkState = true,
    this.canUseStoragePermission = true,
    this.canReadInstalledPackages = true,
    this.installedPackages = defaultInstalledPackages});
}

初始化接口

在用户同意隐私政策前可以调用initWithoutStart方法初始化SDK

method:

class IPDAndroid {
  /// 初始化SDK
  /// 可以在进入应用后立即调用
  /// 返回是否初始化成功
  static void initWithoutStart(

      /// 应用ID
      String appId,
      {
        /// 控制日志打印
        bool isDebug = true,

        /// gdpr状态,-1为未知,0为用户未授权,1为用户授权
        int gdpr = -1,

        /// coppa状态,-1为未知,0为成人,1为儿童
        int coppa = -1,

        /// ccpa状态,-1为未知,0为允许出售,1为不允许出售
        int ccpa = -1,

        /// 用户年龄,默认为0
        int age = 0,

        /// 隐私权限控制
        IPDCustomController? customController});
}

在用户同意隐私政策后调用start方法启动SDK

class IPDAndroid {
  /// 启动SDK
  /// 需要在用户同意隐私政策之后尽快调用
  static void start({
    /// 启动回调
    /// [ret.event] {IPDEventAction.startSuccess | IPDEventAction.startFailed},启动失败时,需要解析ret.code等信息排查
    /// [ret.code]  错误码
    /// [ret.msg]   错误描述
    /// [ret.extra] 错误额外信息
    Function(IPDEvent ret)? onStartListener});
}

example:

/// 初始化SDK
void initSdk() {
  IPDAndroid.initWithoutStart(TestPosId.appId,
      customController: IPDCustomController(canUseAndroidId: true));
  // 判断用户是否同意了隐私政策
  if (_canStart) {
    // 用于已同意隐私政策,调用启动方法,并在成功回调后调用广告
    start();
  } else {
    // 展示隐私政策对话框,并在用户同意后调用`start`方法启动SDK
    showPrivacyDialog(context);
  }
}

/// 启动SDK
void start() {
  IPDAndroid.start(onStartListener: (ret) {
    if (ret.action == IPDEventAction.startSuccess) {
      Fluttertoast.showToast(msg: "初始化成功");
    } else {
      Fluttertoast.showToast(msg: "初始化失败:" + ret.msg!);
      if (kDebugMode) {
        print("${ret.action}:${ret.code}");
      }
    }
  });
}

请求广告

请确保SDK已初始化成功再请求广告

开屏广告

开屏广告分为原生接入与Widget接入,推荐使用原生Activity请求与展示。

原生接入

相比Widget接入方式,原生只需要处理请求失败与关闭回调,不需要处理其他情况,也不需要关闭容器的大小,接入更为简单。

method:

class IPDAndroid {
  /// 加载原生开屏
  static void loadSplashAd(

      /// 广告位ID
      String posId,
      {
        /// 用户ID,选填,用于定位错误日志
        String userId = "",

        /// 自定义背景图的原生资源类型,仅支持(default|mipmap|drawable),其他值无效
        /// default时不需要配置bgResName,SDK会读取原生的默认启动页背景
        /// mipmap或drawable时,需要配置资源名,默认或原生资源不存在时默认主题背景
        String bgResType = "",

        /// 自定义背景图的原生资源名,需要搭配 bgResType 传入,默认开屏页为白色背景
        String bgResName = "",

        /// 开屏回调。具体事件见 example
        Function(IPDEvent ret)? splashListener});
}

example:

/// 原生加载广告
void _loadSplashAd(String posId) {
  IPDAndroid.loadSplashAd(
    // 广告位ID
      posId,
      // 用户ID,选填
      userId: TestPosId.testUserId,
      // 自定义背景图的原生资源类型,仅支持(default|mipmap|drawable),其他值无效
      // default时不需要配置bgResName,SDK会读取原生的默认启动页背景
      // mipmap或drawable时,需要配置资源名,默认或原生资源不存在时默认主题背景
      bgResType: "default",
      // 回调
      splashListener: (ret) {
        // 原生加载仅回调请求失败和关闭
        switch (ret.action) {
        // 请求失败
          case IPDEventAction.onAdLoadFailed:
            Fluttertoast.showToast(msg: "请求开屏失败:${ret.msg}");
            if (kDebugMode) {
              print("${ret.action}:${ret.code}-${ret.extra!}");
            }
            break;
        // 广告关闭
          case IPDEventAction.onAdClose:
            Fluttertoast.showToast(msg: "开屏关闭");
            break;
          default:
          // ignore
        }
      });
}

Widget接入

相比原生接入,Widget接入更加灵活,可以直接嵌入到FlutterView中。但需要处理View的移除,且** 需要保证容器的宽度大于屏幕宽度(非当前界面,是包含顶部StatusBar的整体屏幕)的95%,高度大于屏幕高度的85%**,否则会出现展示无效,不会计费的问题。

widget:

/// 开屏广告视图
class IPDSplashView extends StatelessWidget {
  /// 广告位ID
  final String posId;

  /// 用户ID
  final String userId;

  /// 宽
  final double width;

  /// 高
  final double height;

  /// 回调
  final Function(IPDEvent ret) splashListener;

  const IPDSplashView(this.posId,
      {Key? key,
        required this.width,
        required this.height,
        this.userId = "",
        required this.splashListener})
      : super(key: key);
}

example:

child:
  IPDSplashView
    (
// 广告位ID
    posId,
// 用户ID,选填
    userId: TestPosId.testUserId,
    width: double.infinity,
    height: double.infinity,
// 回调
    splashListener: (ret) {
      switch (ret.action) {
// 加载失败
        case IPDEventAction.onAdLoadFailed:
          Fluttertoast.showToast(msg: "开屏请求失败:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          _reset();
          break;
// 展示错误
        case IPDEventAction.onAdShowError:
          Fluttertoast.showToast(msg: "开屏展示错误:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          _reset();
          break;
// 展示成功
        case IPDEventAction.onAdShow:
          Fluttertoast.showToast(msg: "开屏展示");
          break;
// 点击广告
        case IPDEventAction.onAdClick:
          Fluttertoast.showToast(msg: "开屏点击");
          break;
// 关闭
        case IPDEventAction.onAdClose:
          Fluttertoast.showToast(msg: "开屏关闭");
          _reset();
          break;
        default:
// ignore
      }
    },
  ),

激励视频

激励视频会弹出一个新的页面,用户观看达到一定时长时才可以跳过并退出,SDK会回调发奖。 激励视频分为加载并展示预加载->手动展示两种方式,无特殊需要建议使用加载并展示方式接入

加载并展示

调用加载并展示时,不需要额外判断广告加载情况和处理预加载广告对象过期后重新请求的问题。 需要屏蔽用户的重复点击操作,防止用户频繁点击导致的广告嵌套播放

method:

class IPDAndroid {
  /// 加载激励视频
  static void loadRewardVideo(

      /// 广告位ID
      String posId,

      /// 用户ID,必填
      String userId,

      /// 回调。具体事件见 example
      Function(IPDEvent ret) rewardListener, {
        /// 是否开启视频声音
        bool videoSoundEnable = true,

        /// 透传信息(返回到服务端发校验接口)
        String extra = "",

        /// 是否为预加载,默认false
        /// 非预加载时,加载成功后直接播放
        /// 预加载时仅回调成功/失败,需要搭配[showRewardVideo]方法展示
        bool isPreLoad = false,
      });
}

example:

 /// 加载并展示激励视频
void _loadRewardVideo(BuildContext context, String posId) {
  // 展示加载中对话框,防止用户重复点击
  _showLoading(context);
  setState(() {
    // 请求状态
    isRequesting = true;
  });
  IPDAndroid.loadRewardVideo(
    // 广告位ID
      posId,
      // 用户ID,必填
      TestPosId.testUserId,
      // 回调
          (ret) {
        switch (ret.action) {
        // 加载失败
          case IPDEventAction.onAdLoadFailed:
            Navigator.of(context).pop();
            _reset(context);
            Fluttertoast.showToast(msg: "激励视频加载失败:${ret.msg}");
            if (kDebugMode) {
              print("${ret.action}:${ret.code}-${ret.extra!}");
            }
            break;
        // 展示错误
          case IPDEventAction.onAdShowError:
            Navigator.of(context).pop();
            _reset(context);
            Fluttertoast.showToast(msg: "激励视频播放错误:${ret.msg}");
            if (kDebugMode) {
              print("${ret.action}:${ret.code}-${ret.extra!}");
            }
            break;
        // 展示成功
          case IPDEventAction.onAdShow:
            Fluttertoast.showToast(msg: "激励视频展示");
            break;
        // 点击广告
          case IPDEventAction.onAdClick:
            Fluttertoast.showToast(msg: "激励视频点击");
            break;
        // 满足条件,可以发奖
          case IPDEventAction.onAdRewardVerify:
            Fluttertoast.showToast(msg: "激励视频发奖");
            break;
        // 关闭
          case IPDEventAction.onAdClose:
            Navigator.of(context).pop();
            _reset(context);
            Fluttertoast.showToast(msg: "激励视频关闭");
            break;
          default:
          // ignore
        }
      });
}

预加载->手动展示

建议使用加载并展示方式请求广告。使用预加载时需要指定属性isPreLoad: true 预加载模式需要判断加载状态,加载成功的回调后再播放广告,否则回调播放错误。 广告的请求行为与展示行为是对应关系,即一次请求对应一次展示,重复展示时会报错。 预加载广告的有效时间为20分钟,过期后展示会回调错误,需要重新请求。 预加载对于Flutter全局缓存一个对象,不需要在每个页面去单独预加载。 可以重复预加载广告,新返回的广告对象会替换旧对象。

method:

class IPDAndroid {
  /// 加载激励视频
  static void loadRewardVideo(

      /// 广告位ID
      String posId,

      /// 用户ID,必填
      String userId,

      /// 回调。具体事件见 example
      Function(IPDEvent ret) rewardListener, {
        /// 是否开启视频声音
        bool videoSoundEnable = true,

        /// 透传信息(返回到服务端发校验接口)
        String extra = "",

        /// 是否为预加载,默认false
        /// 非预加载时,加载成功后直接播放
        /// 预加载时仅回调成功/失败,需要搭配[showRewardVideo]方法展示
        bool isPreLoad = false,
      });

  /// 展示激励视频
  static void showRewardVideo(

      /// 展示回调
      Function(IPDEvent ret)? rewardListener);
}

example:

 /// 预加载激励视频
void _preloadRewardVideo(String posId) {
  IPDAndroid.loadRewardVideo(posId, TestPosId.testUserId, (ret) {
    // 预加载仅回调加载失败和加载成功
    switch (ret.action) {
    // 加载失败
      case IPDEventAction.onAdLoadFailed:
        _reset(context);
        Fluttertoast.showToast(msg: "请求激励视频失败:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        break;
    // 加载成功
      case IPDEventAction.onAdLoaded:
        _reset(context);
        Fluttertoast.showToast(msg: "激励视频加载成功");
        break;
      default:
        break;
    }
  },
      // 指定预加载
      isPreLoad: true);
}

/// 展示激励视频
/// 仅预加载时需要手动调用展示方法
/// 需要预加载请求回调[IPDEventAction.onAdLoaded]调用,否则回调错误
/// 预加载状态全局生效,有效期20分钟,过期时会在播放时回调错误
void _showRewardVideo() {
  IPDAndroid.showRewardVideo((ret) {
    switch (ret.action) {
    // 播放错误,如未加载、广告已过期、原生Activity无效等情况,需要重新加载广告
      case IPDEventAction.onAdShowError:
        Fluttertoast.showToast(msg: "激励视频播放错误:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        break;
    // 展示成功
      case IPDEventAction.onAdShow:
        Fluttertoast.showToast(msg: "激励视频展示");
        break;
    // 点击广告
      case IPDEventAction.onAdClick:
        Fluttertoast.showToast(msg: "激励视频点击");
        break;
    // 满足条件,可以发奖
      case IPDEventAction.onAdRewardVerify:
        Fluttertoast.showToast(msg: "激励视频发奖");
        break;
    // 关闭
      case IPDEventAction.onAdClose:
        Fluttertoast.showToast(msg: "激励视频关闭");
        break;
      default:
      // ignore
    }
  });
}

插屏广告

插屏广告会在当前界面上层弹出一个类似对话框的页面,用户可以手动关闭。 插屏广告会在加载成功后自动播放。

method:

class IPDAndroid {
  /// 插屏
  static void interstitial(

      /// 广告位ID
      String posId, {
        /// 用户ID,选填
        String userId = "",

        /// 是否开启视频声音
        bool videoSoundEnable = true,

        /// 回调。具体事件见 example
        Function(IPDEvent ret)? interstitialListener,
      });
}

example:

 /// 加载并展示插屏广告
void _interstitial(String posId) {
  setState(() {
    isRequesting = true;
  });
  IPDAndroid.interstitial(
    // 广告位ID
      posId,
      // 用户ID,选填
      userId: TestPosId.testUserId,
      // 视频类素材是否开启声音,默认true
      videoSoundEnable: true, interstitialListener: (ret) {
    switch (ret.action) {
    // 请求失败
      case IPDEventAction.onAdLoadFailed:
        Fluttertoast.showToast(msg: "请求插屏失败:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        _reset();
        break;
    // 展示错误
      case IPDEventAction.onAdShowError:
        Fluttertoast.showToast(msg: "插屏展示错误:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        _reset();
        break;
    // 展示成功
      case IPDEventAction.onAdShow:
        Fluttertoast.showToast(msg: "插屏展示");
        break;
    // 点击广告
      case IPDEventAction.onAdClick:
        Fluttertoast.showToast(msg: "插屏点击");
        break;
    // 关闭
      case IPDEventAction.onAdClose:
        Fluttertoast.showToast(msg: "插屏关闭");
        _reset();
        break;
      default:
      // ignore
    }
  });
}

全屏广告

全屏广告会弹出一个新的页面播放图文或视频,用户可以直接关闭并退出。

method:

class IPDAndroid {
  /// 全屏广告
  static void fullScreenAd(

      /// 广告位ID
      String posId, {
        /// 用户ID,选填
        String userId = "",

        /// 是否开启视频声音
        bool videoSoundEnable = true,

        /// 回调。具体事件见 example
        Function(IPDEvent ret)? fullScreenAdListener,
      });
}

example:

/// 加载并展示全屏广告
void _fullScreenAd(String posId) {
  setState(() {
    isRequesting = true;
  });
  IPDAndroid.fullScreenAd(
    // 广告位ID
      posId,
      // 用户ID,选填
      userId: TestPosId.testUserId,
      // 视频类素材是否开启声音,默认true
      videoSoundEnable: true, fullScreenAdListener: (ret) {
    switch (ret.action) {
    // 请求失败
      case IPDEventAction.onAdLoadFailed:
        Fluttertoast.showToast(msg: "请求全屏失败:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        _reset();
        break;
    // 展示错误
      case IPDEventAction.onAdShowError:
        Fluttertoast.showToast(msg: "全屏展示错误:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        _reset();
        break;
    // 展示成功
      case IPDEventAction.onAdShow:
        Fluttertoast.showToast(msg: "全屏展示");
        break;
    // 点击广告
      case IPDEventAction.onAdClick:
        Fluttertoast.showToast(msg: "全屏点击");
        break;
    // 关闭
      case IPDEventAction.onAdClose:
        Fluttertoast.showToast(msg: "全屏关闭");
        _reset();
        break;
      default:
      // ignore
    }
  });
}

横幅广告

横幅广告为插入页面的Widget,一般需要宽度占满屏幕,高度按照固定比例计算,当容器大于模板高度时会自动居中,接入时需要与我们确定尺寸比例。

widget:

/// 横幅广告视图
class IPDBannerView extends StatelessWidget {
  /// 广告位ID
  final String posId;

  /// 用户ID
  final String userId;

  /// 自刷新频率(单位s,仅部分广告生效,0时不刷新)
  final int refreshInterval;

  /// 宽
  final double width;

  /// 高
  final double height;

  /// 回调
  final Function(IPDEvent ret)? bannerListener;

  const IPDBannerView(this.posId,
      {Key? key,
        required this.width,
        required this.height,
        this.userId = "",
        this.refreshInterval = 0,
        this.bannerListener})
      : super(key: key);
}

example:

child:
  IPDBannerView
    (
// 广告位ID
    posId,
    width: double.infinity,
// 需要固定高度
    height: 80,
    userId: TestPosId.testUserId,
    bannerListener: (ret) {
      switch (ret.action) {
        case IPDEventAction.onAdLoadFailed:
          Fluttertoast.showToast(msg: "Banner1请求失败:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          break;
        case IPDEventAction.onAdShowError:
          Fluttertoast.showToast(msg: "Banner1展示错误:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          break;
        case IPDEventAction.onAdShow:
          Fluttertoast.showToast(msg: "Banner1展示");
          break;
        case IPDEventAction.onAdClick:
          Fluttertoast.showToast(msg: "Banner1点击");
          break;
        case IPDEventAction.onAdClose:
          Fluttertoast.showToast(msg: "Banner1关闭");
          break;
        default:
// ignore
      }
    },
  ),

信息流广告

信息流广告为插入页面的Widget,一般需要宽度占满屏幕,高度按照固定比例计算,当容器大于模板高度时会自动居中,接入时需要与我们确定尺寸比例。 相比横幅广告,信息流广告的模板样式更丰富,展现场景更灵活。

widget:

/// 信息流广告视图
class IPDNativeExpressView extends StatelessWidget {
  /// 广告位ID
  final String posId;

  /// 用户ID
  final String userId;

  /// 视频类型素材的声音开关
  final bool videoSoundEnable;

  /// 宽
  final double width;

  /// 高
  final double height;

  /// 回调
  final Function(IPDEvent ret)? nativeExpressListener;

  const IPDNativeExpressView(this.posId,
      {Key? key,
        required this.width,
        required this.height,
        this.userId = "",
        this.videoSoundEnable = false,
        this.nativeExpressListener})
      : super(key: key);
}

example:

child:
  IPDNativeExpressView(
    // 广告位ID
    posId,
    width: double.infinity,
    // 需要指定高度
    height: 300,
    // 用户ID,选填
    userId: TestPosId.testUserId,
    nativeExpressListener: (ret) {
      switch (ret.action) {
        case IPDEventAction.onAdLoadFailed:
        // 请求失败
          Fluttertoast.showToast(msg: "信息流1请求失败:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          break;
      // 展示错误
        case IPDEventAction.onAdShowError:
          Fluttertoast.showToast(msg: "信息流1展示错误:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          break;
      // 展示成功
        case IPDEventAction.onAdShow:
          Fluttertoast.showToast(msg: "信息流1展示");
          break;
      // 点击广告
        case IPDEventAction.onAdClick:
          Fluttertoast.showToast(msg: "信息流1点击");
          break;
      // 关闭
        case IPDEventAction.onAdClose:
          Fluttertoast.showToast(msg: "信息流1关闭");
          break;
        default:
        // ignore
      }
    },
  ),

视频流广告

视频流广告的模板样式为竖屏,适用于插入到应用已有的视频流中。

widget:

/// 视频流广告视图
class IPDDrawAdView extends StatelessWidget {
  /// 广告位ID
  final String posId;

  /// 用户ID
  final String userId;

  /// 视频类型素材的声音开关
  final bool videoSoundEnable;

  /// 宽
  final double width;

  /// 高
  final double height;

  /// 回调
  final Function(IPDEvent ret)? drawAdListener;

  const IPDDrawAdView(this.posId,
      {Key? key,
        required this.width,
        required this.height,
        this.userId = "",
        this.videoSoundEnable = true,
        this.drawAdListener})
      : super(key: key);
}

example:

child: {
  IPDDrawAdView(
    // 广告位ID
    posId,
    width: double.infinity,
    height: double.infinity,
    // 用户ID,选填
    userId: TestPosId.testUserId,
    drawAdListener: (ret) {
      switch (ret.action) {
      // 请求失败
        case IPDEventAction.onAdLoadFailed:
          Fluttertoast.showToast(msg: "视频流请求失败:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          break;
      // 展示错误
        case IPDEventAction.onAdShowError:
          Fluttertoast.showToast(msg: "视频流展示错误:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          break;
      // 展示成功
        case IPDEventAction.onAdShow:
          Fluttertoast.showToast(msg: "视频流展示");
          break;
      // 点击广告
        case IPDEventAction.onAdClick:
          Fluttertoast.showToast(msg: "视频流点击");
          break;
      // 关闭
        case IPDEventAction.onAdClose:
          Fluttertoast.showToast(msg: "视频流关闭");
          break;
        default:
        // ignore
      }
    },
  ),

视频内容

视频内容分为原生加载Widget加载。使用原生加载会在应用上层弹出新界面进行展示,性能更好。使用Widget加载可以嵌入到Flutter界面中,使用更加灵活。

**注意:**使用Widget加载时,需要确保 Android 的MainActivity继承io.flutter.embedding.android.FlutterFragmentActivity,Flutter 会默认继承 io.flutter.embedding.android.FlutterActivity。详见example/MainActivity

原生加载

method:

class IPDAndroid {
  /// 原生展示视频内容
  static void contentAd(

      /// 广告位ID
      String posId, {
        /// 用户ID,选填
        String userId = "",

        /// 回调。具体事件见 example
        Function(IPDEvent ret)? contentAdListener,
      });
}

example:

/// 原生加载广告
void _loadContentAd(String posId) {
  IPDAndroid.contentAd(
    // 广告位ID
      posId,
      // 用户ID,选填
      userId: TestPosId.testUserId, contentAdListener: (ret) {
    switch (ret.action) {
      case IPDEventAction.onAdLoadFailed:
        Fluttertoast.showToast(msg: "视频内容请求失败:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        break;
      case IPDEventAction.onAdClose:
        Fluttertoast.showToast(msg: "视频内容关闭");
        break;
      default:
      // ignore
    }
  });
}

widget加载

widget:

/// 视频内容视图
class IPDContentAdView extends StatelessWidget {
  /// 广告位ID
  final String posId;

  /// 用户ID
  final String userId;

  /// 宽
  final double width;

  /// 高
  final double height;

  /// 回调
  final Function(IPDEvent ret)? contentAdListener;

  const IPDContentAdView(this.posId,
      {Key? key,
        required this.width,
        required this.height,
        this.userId = "",
        this.contentAdListener})
      : super(key: key);
}

example:

child:
  PDContentAdView(
    // 广告位ID
    posId,
    // 用户ID,选填
    userId: TestPosId.testUserId,
    width: double.infinity,
    height: double.infinity,
    contentAdListener: (ret) {
      switch (ret.action) {
      // 请求失败,请根据msg和extra进行排查
        case IPDEventAction.onAdLoadFailed:
          Fluttertoast.showToast(msg: "视频内容请求失败:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          _reset();
          break;
      // 展示错误
        case IPDEventAction.onAdShowError:
          Fluttertoast.showToast(msg: "视频内容展示错误:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          _reset();
          break;
      // 展示成功
        case IPDEventAction.onAdShow:
          Fluttertoast.showToast(msg: "视频内容展示");
          break;
      // 关闭
        case IPDEventAction.onAdClose:
          Fluttertoast.showToast(msg: "视频内容关闭");
          break;
        default:
        // ignore
      }
    },
  ),

新闻资讯

新闻资讯分为原生加载widget加载,可作为任务模块加载,用户阅读的篇数和时长达到条件时会发放奖励。也可以不配置任务条件仅作为内容填充。

**注意:**使用Widget加载时,需要确保 Android 的MainActivity继承io.flutter.embedding.android.FlutterFragmentActivity,Flutter 会默认继承 io.flutter.embedding.android.FlutterActivity。详见example/MainActivity

原生加载

method:

class IPDAndroid {
  /// 原生展示新闻资讯
  static void newsAd(

      /// 广告位ID
      String posId,

      /// 用户ID,必填
      String userId, {
        /// 回调。具体事件见 example
        Function(IPDEvent ret)? newsAdListener,
      });
}

example:

/// 原生加载广告
void _loadNewsAd(String posId) {
  IPDAndroid.newsAd(
    // 广告位ID
      posId,
      // 用户ID,必填
      TestPosId.testUserId, newsAdListener: (ret) {
    switch (ret.action) {
    // 请求失败,请根据msg和extra进行排查
      case IPDEventAction.onAdLoadFailed:
        Fluttertoast.showToast(msg: "新闻资讯请求失败:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        break;
    // 满足任务条件,可以发奖(仅配置任务时在关闭前回调)
      case IPDEventAction.onAdRewardVerify:
        Fluttertoast.showToast(msg: "新闻资讯发奖");
        break;
    // 关闭
      case IPDEventAction.onAdClose:
        Fluttertoast.showToast(msg: "新闻资讯关闭");
        break;
      default:
      // ignore
    }
  });
}

widget加载

widget:

/// 新闻资讯视图
class IPDNewsAdView extends StatelessWidget {
  /// 广告位ID
  final String posId;

  /// 用户ID
  final String userId;

  /// 宽
  final double width;

  /// 高
  final double height;

  /// 回调
  final Function(IPDEvent ret)? newsAdListener;

  const IPDNewsAdView(this.posId,
      {Key? key,
        required this.width,
        required this.height,
        this.userId = "",
        this.newsAdListener})
      : super(key: key);
}

example:

child:
  IPDNewsAdView(
    // 广告位ID
    posId,
    // 用户ID,必填
    userId: TestPosId.testUserId,
    width: double.infinity,
    height: double.infinity,
    newsAdListener: (ret) {
      switch (ret.action) {
      // 请求失败,请根据msg和extra进行排查
        case IPDEventAction.onAdLoadFailed:
          Fluttertoast.showToast(msg: "新闻资讯请求失败:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          _reset();
          break;
      // 展示错误
        case IPDEventAction.onAdShowError:
          Fluttertoast.showToast(msg: "新闻资讯展示错误:${ret.msg}");
          if (kDebugMode) {
            print("${ret.action}:${ret.code}-${ret.extra!}");
          }
          _reset();
          break;
      // 展示成功
        case IPDEventAction.onAdShow:
          Fluttertoast.showToast(msg: "新闻资讯展示");
          break;
      // 满足任务条件,可以发奖(仅配置任务时回调)
        case IPDEventAction.onAdRewardVerify:
          Fluttertoast.showToast(msg: "新闻资讯发奖");
          break;
      // 关闭
        case IPDEventAction.onAdClose:
          Fluttertoast.showToast(msg: "新闻资讯关闭");
          break;
        default:
        // ignore
      }
    },
  ),

H5页面

H5页面会弹出新层级的界面,展示H5插件页面。用户在页面中进行浏览和互动。

method:

class IPDAndroid {
  /// H5页面
  static void h5Page(

      /// 广告位ID
      String posId,

      /// 用户ID,必填
      String userId, {
        /// 回调。具体事件见 example
        Function(IPDEvent ret)? h5PageListener,
      });
}

example:

/// 加载并展示插屏广告
void _h5Page(String posId) {
  IPDAndroid.h5Page(
    // 广告位ID
      posId,
      // 用户ID,必填
      TestPosId.testUserId, h5PageListener: (ret) {
    switch (ret.action) {
      case IPDEventAction.onAdLoadFailed:
        Fluttertoast.showToast(msg: "H5页面请求失败:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        break;
      case IPDEventAction.onAdShowError:
        Fluttertoast.showToast(msg: "H5页面展示错误:${ret.msg}");
        if (kDebugMode) {
          print("${ret.action}:${ret.code}-${ret.extra!}");
        }
        break;
      case IPDEventAction.onAdClose:
        Fluttertoast.showToast(msg: "H5页面关闭");
        break;
      default:
      // ignore
    }
  });
}