跳到主要内容

章鱼广告 SDK-Android 接入文档

注意:

  • 本 SDK 最低兼容 Android API 16(Android 4.1 ICS)

  • 确保 support v4、v7 包版本不小于 `24.0.0

  • 竞胜竞败回传:章鱼广告平台根据媒体传回来的竞胜竞败价格,通过相应算法自动提高出价来获得广告曝光,媒体 RTB 时一定要调用,否则会导致价格出不上去。

一、导入 SDK 依赖

1.1、压缩包目录结构

  • 文件目录目录说明
    Octopus/libs/***.aar项目中依赖的 aar 文件.
    OctopusSdkDemo示例工程, 用来方便媒体参考接入.
    demo-release.apk示例 APP, 用来演示章鱼广告提供的多种广告展现形式.
    README.md章鱼广告 SDK-Android 接入文档.

1.2、导入 SDK 文件

​ 1.2.1、在 app 目录下新建 libs 文件夹.

​ 1.2.2、将 Octopus/libs 目录下的文件拷贝到 libs 文件夹下.

​ 1.2.3、在 app/build.gradle 添加如下代码:

  • android {
    compileSdkVersion 28

    // 设置gradle编译选项,开发者可以根据自己对平台的选择进行合理配置,为了保证兼容性,默认支持以下两种架构
    ndk {
    abiFilters 'armeabi-v7a','arm64-v8a'
    }


    repositories {
    flatDir {
    dirs 'libs'
    }
    }

    dependencies {
    // 集成章鱼广告SDK需导入的aar
    implementation(name: 'octopus_ad_sdk_1.6.1.9', ext: 'aar')
    }

1.3、AndroidManifest 配置

​ 1.3.1、添加访问权限

​ 在 AndroidManifest.xml 文件中添加,建议在您的隐私协议中向开发者声明章鱼聚合 SDK 会获取下述权限并应用于广告投放

  • <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

​ 注意:章鱼广告 SDK 不强制获取可选权限,即使没有获取可选权限 SDK 也能正常运行

​ 1.3.2、overrideLibrary 设置

​ 由于引入的 sdk 支持的最小版本与 app 支持的最小版本可能不一致,需要在 AndroidManifest 文件中添加 overrideLibrary 配置:

  • <uses-sdk tools:overrideLibrary="com.octopus.ad" />

​ 注意:请开发者务必按照上面信息进行注册声明,详情见 Demo。

​ 1.3.3、配置网络权限

​ 在 targetSdkVersion 28 及以上的手机上允许 HTTP(S)网络请求,在“AndroidManifest.xml”做以下配置。

  • <application
    ...
    android:usesCleartextTraffic="true"
    >
    ...
    </application>

​ 1.3.4、开启硬件加速

​ 视频广告的 MediaView 内部使用了 TextureView,需要在开启硬件加速的窗口中才能使用。 ​ 所以需要在 AndroidManifest.xml 添加如下声明:

  • 方式一:
    <application

    android:hardwareAccelerated="true"
    ... ...

    </application>

    方式二:
    <activity

    android:hardwareAccelerated="true"
    ... ...

    </activity>

1.4、混淆配置

​ 为了保证 Octopus SDK 正常工作, 请务必添加以下 ProGuard 配置打包.

  • # Octopus混淆
    -dontwarn com.octopus.**
    -keep class com.octopus.** {*;}

二、SDK 初始化

2.1、初始化 SDK

​ 注意:①、初始化 SDK 必须在调用广告接口之前。appId 由运营人员提供

​ ②、建议在 application 里面调用;假如 App 有功能引导,也可点击"立即体验"按钮中调用

​ ③、在主线程中调用 sdk 的初始化(init)方法

​ 2.1.1、如需不需要自定义隐私开关控制,请调用如下方法

  • Octopus.init(applicationContext, appId);

​ 2.1.2、如需自定义隐私开关控制,请调用如下方法

  • Octopus.init(applicationContext, appId , new OctopusAdSdkController());

2.2、隐私信息控制开关

  • /**
    * 创建隐私信息控制 实例,媒体可以自主控制是否提供权限给广告sdk使用
    * 重要!!重要!!
    * 为了保证广告的填充率,注意oaid和imei的配置:
    * (1)oaid 开发者可以接入信通院OAID,并传入有效值,如果开发者不传入oaid,sdk会自动获取oaid
    * (2)imei的配置与isCanUsePhoneState有关(isCanUsePhoneState配置项默认为true)
    * 当isCanUsePhoneState 配置为false,不允许SDK主动获取imei,但是需要接入方主动传入imei
    * 当isCanUsePhoneState 配置为true,允许SDK主动获取imei,但必须保证接入方已经动态申请了 Manifest.permission.READ_PHONE_STATE,否则SDK会获取失败
    */
    public abstract class OctopusAdSdkController {

    /**
    * 是否允许SDK主动使用手机硬件参数,如:imei
    *
    * @return true可以使用,false禁止使用。默认为true
    */
    public boolean isCanUsePhoneState() {
    return true;
    }

    /**
    * 当isCanUsePhoneState=false时,可传入imei信息,sdk使用您传入的imei信息
    * @return imei信息
    */
    public String getImei() {
    return "";
    }

    /**
    * 开发者可以传入oaid
    * 信通院OAID的相关采集——如何获取OAID:
    * 1. 移动安全联盟官网http://www.msa-alliance.cn/
    * 2. 信通院统一SDK下载http://msa-alliance.cn/col.jsp?id=120
    *
    * @return oaid
    */
    public String getOaid() {
    return "";
    }
    }

2.3、其它特殊设置

​ 2.3.1、设置下载类广告是否直接下载 APP,默认开启下载二次确认弹窗

  • Octopus.setIsDownloadDirect(false); // 是否不弹窗,直接下载。默认为false

​ 2.3.2、设置是否限制个性化广告推荐 (请在用户点击关闭个性化广告推荐时才调用此方法,否则影响广告收益)

  • Octopus.setLimitPersonalAds(false); // 不限制个性化广告推荐。默认为false

​ 2.3.3、设置广告请求超时时长(单位毫秒)

  • Octopus.setTimeout(1000);

三、开屏广告

3.1、添加广告容器

​ 在需要添加开屏广告的 Activity 对应的布局文件添加一个 ViewGroup 来填充广告,例如:

  • <FrameLayout
    android:id="@+id/fl_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/rl_bottom" />

3.2、开屏广告接口说明

  • /**
    * 先传入adContainer和showAd()配套使用
    * @param context 上下文
    * @param adSlotId 广告位id,由运营人员提供
    * @param adContainer 广告容器
    * @param adListener 开屏广告监听器
    */
    public SplashAd(Context context, String adSlotId, ViewGroup adContainer, SplashAdListener adListener)

    /**
    * 不传入adContainer和showAd(ViewGroup adContainer)配套使用
    * @param context 上下文
    * @param adSlotId 广告位id,由运营人员提供
    * @param adListener 开屏广告监听器
    */
    public SplashAd(Context context, String adSlotId, SplashAdListener adListener)

    /**
    * 是否使用SDK内部浏览器打开落地页
    * @param isOpenInNativeBrowser 默认false, true使用SDK内部浏览器打开, false使用本地浏览器打开
    */
    public void openAdInNativeBrowser(boolean isOpenInNativeBrowser)

    /**
    * 广告是否加载成功
    * @return true表示加载成功
    */
    public boolean isLoaded()

    /**
    * 广告是否加载成功,并且在有效时间内(有做广告预缓存的用这个)
    * @return true表示加载成功并且有效
    */
    public boolean isValid()

    /**
    * 广告加载成功后可以获取广告返回价格,单位分
    */
    public int getPrice()

    /**
    * 配合SplashAd(Context context, String adSlotId, ViewGroup adContainer, SplashAdListener adListener)使用
    */
    public void showAd()

    /**
    * 配合SplashAd(Context context, String adSlotId, SplashAdListener adListener)使用
    */
    public void showAd(ViewGroup adContainer)

    /**
    * 资源释放
    */
    public void destroy()

3.3、开屏广告回调说明

  • /**
    * 开屏广告监听器
    */
    SplashAdListener {
    /**
    * 广告加载成功
    */
    void onAdLoaded();

    /**
    * 素材缓存完成
    * @param isSuccess 是否缓存成功
    */
    void onAdCacheLoaded(boolean isSuccess);

    /**
    * 广告展示
    */
    void onAdShown();

    /**
    * 加载失败
    * @param errorCode 错误码
    */
    void onAdFailedToLoad(int errorCode);

    /**
    * 广告关闭
    */
    void onAdClosed();

    /**
    * 倒计时回调,返回广告还将被展示的剩余时间。
    * 通过这个接口,开发者可以自行决定是否显示倒计时提示,或者还剩几秒的时候显示倒计时
    */
    void onAdTick(long millisUnitFinished);

    /**
    * 广告点击
    */
    void onAdClicked();
    }

3.4、开屏广告示例

  • 创建开屏广告实例:

    FrameLayout container = this.findViewById(R.id.fl_container);
    SplashAdListener listener = new SplashAdListener() {
    @Override
    public void onAdLoaded() {
    Log.i(TAG, "onAdLoaded");
    // 广告在此竞价 mSplashAd.getPrice(); 单位分
    // 注意:竞价结束后记得调用竞胜或竞败接口
    // 竟胜时候调用(提高ECPM, 提升填充率)
    // mSplashAd.sendWinNotice(第二高价格);
    // 竟败时候调用(提高ECPM, 提升填充率)
    // mSplashAd.sendLossNotice(最高价, ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.OTHER);
    }

    @Override
    public void onAdCacheLoaded(boolean isSuccess) {
    Log.i(TAG, "onAdCacheLoaded: " + isSuccess);
    // 图片素材和视频资源缓存到本地的回调,在此展示效果最好。
    // 注意:视频等资源缓存失败会回调onAdFailedToLoad
    // 广告是否加载成功并且在有效时间内
    // isSuccess可以用来判断是否缓存成功,没缓存成功也可以播放在线视频
    if (mSplashAd.isValid()) {
    mSplashAd.showAd();
    }
    }

    @Override
    public void onAdShown() {
    Log.i(TAG, "onAdShown");
    }

    @Override
    public void onAdFailedToLoad(int errorCode) {
    Log.i(TAG, "onAdFailedToLoad:" + errorCode);
    jump();
    }

    @Override
    public void onAdClosed() {
    Log.i(TAG, "onAdClosed");
    jumpWhenAdPageFinish();
    }

    @Override
    public void onAdClicked() {
    Log.i(TAG, "onAdClicked");
    }

    @Override
    public void onAdTick(long millisUnitFinished) {
    Log.i(TAG, "onAdTick " + millisUnitFinished);
    }
    };
    mSplashAd = new SplashAd(this, slotId, container, listener);
  • 开屏页一定要禁止用户对返回按钮的控制,否则将可能导致用户手动退出了 App 而广告无法正常曝光和计费:

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME) {
    return true;
    }
    return super.onKeyDown(keyCode, event);
    }
  • 开屏页的 onDestroy 方法中请调用:

    @Override
    protected void onDestroy() {
    if (mSplashAd != null) {
    mSplashAd.destroy();
    }
    super.onDestroy();
    }
  • 解决点击广告后页面跳转问题(点击后应该先跳转到广告落地页,从落地页返回再进入应用主页),请参考 demo 中如下写法

    // 如果用户点击广告,需要等待广告页面关闭后再跳转主页面。
    public boolean mCanJumpImmediately = false;

    // 立即跳转主页面
    private void jump() {
    startActivity(new Intent(SplashActivity.this, MainActivity.class));
    finish();
    }

    // 如果用户点击广告,需要等待广告页面关闭后再跳转主页面。
    private void jumpWhenAdPageFinish() {
    if (mCanJumpImmediately) {
    jump();
    } else {
    mCanJumpImmediately = true;
    }
    }

    @Override
    protected void onResume() {
    super.onResume();
    if (mCanJumpImmediately) {
    jumpWhenAdPageFinish();
    }
    mCanJumpImmediately = true;
    }

    @Override
    protected void onPause() {
    super.onPause();
    mCanJumpImmediately = false;
    }

3.5、开屏广告的验证

​ 3.5.1、开屏广告显示,用户点击跳过按钮,可正常跳过(跳转到目标界面)

​ 3.5.2、开屏广告显示,用户正常观看广告若干秒(比如 5 秒),跳过按钮自动消失,可正常跳转(跳转到目标界面)

​ 3.5.3、开屏广告显示,用户点击广告显示广告落地页,关闭广告落地页后跳转到目标界面

  • PS:完整流程请参考 Demo 中的 com.octopus.sdk.demo.SplashActivity 的示例代码。

四、原生(信息流)广告

4.1、原生广告接口说明

  • /**
    * 原生广告构造方法
    * @param context 上下文
    * @param adSlotId 广告位id,由运营人员提供
    * @param nativeAdListener 原生广告监听
    */
    public NativeAd(Context context, String adSlotId, NativeAdListener nativeAdListener)

    /**
    * 是否使用SDK内部浏览器打开落地页
    * @param isOpenInNativeBrowser 默认false, true使用SDK内部浏览器打开, false使用本地浏览器打开
    */
    public void openAdInNativeBrowser(boolean isOpenInNativeBrowser)

    /**
    * 广告加载成功后可以获取广告返回价格,单位分
    */
    public int getPrice()

    /**
    * 加载广告
    */
    public void loadAd()

    /**
    * 广告是否加载成功
    * @return true表示加载成功
    */
    public boolean isLoaded()

    /**
    * 广告是否加载成功,并且在有效时间内(有做广告预缓存的用这个)
    * @return true表示加载成功并且有效
    */
    public boolean isValid()

    /**
    * 资源释放
    */
    public void destroy()

4.2、原生广告回调说明

  • /**
    * 原生广告加载监听器
    */
    NativeAdListener {
    /**
    * 广告加载失败
    * @param errorCode 错误码
    */
    void onAdFailed(int errorCode);

    /**
    * 广告加载成功
    * @param response 原生广告响应数据
    */
    void onAdLoaded(NativeAdResponse response);
    }

    /**
    * 原生广告事件监听器
    */
    NativeAdEventListener {
    /**
    * 广告点击
    */
    void onAdClick();
    /**
    * 广告曝光
    */
    void onADExposed();
    /**
    * 广告渲染失败
    * @param errorCode 错误码
    */
    void onAdRenderFailed(int errorCode);
    /**
    * 广告关闭
    */
    void onAdClose();
    }

4.3、原生广告示例

  • 创建原生广告实例:

    LinearLayout adContainer = findViewById(R.id.ad_container);
    mNativeAd = new NativeAd(this, slotId, new NativeAdListener() {
    @Override
    public void onAdFailed(int errorCode) {
    Log.d(TAG, "onAdFailed:" + errorCode);
    Toast.makeText(activity, "onAdFailedToLoad reason: " + errorCode, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onAdLoaded(NativeAdResponse response) {
    Log.d(TAG, "onAdLoaded");
    // 广告是否加载成功并且在有效时间内
    if (mNativeAd != null && mNativeAd.isValid()) {
    int adWidth = ViewUtil.getScreenWidth(NativeActivity.this);
    // 设置广告的宽度单位px(防止SDK获取不到容器的宽度)
    response.setAdWidth(adWidth);
    showNativeAd(response);
    }
    // 注意:竞价结束后记得调用竞胜或竞败接口
    // 竟胜时候调用(提高ECPM, 提升填充率)
    // mNativeAd.sendWinNotice(第二高价格);
    // 竟败时候调用(提高ECPM, 提升填充率)
    // mNativeAd.sendLossNotice(最高价, ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.OTHER);
    });
    }
    });
    // 使用SDK内部浏览器打开落地页(默认为false,设为false的情况下会使用本地浏览器打开)
    mNativeAd.openAdInNativeBrowser(true);
    mNativeAd.loadAd();

    public void showNativeAd(NativeAdResponse response) {
    if (response == null) return;
    // 渲染原生模板广告有两种方式,二选一
    // 方式一:先设置曝光点击监听,再获取原生广告View
    response.setNativeAdEventListener(new NativeAdEventListener() {
    @Override
    public void onAdClick() {
    Log.i(TAG, "onAdClick");
    }

    @Override
    public void onADExposed() {
    Log.i(TAG, "onADExposed");
    }

    @Override
    public void onAdRenderFailed(int errorCode) {
    Log.i(TAG, "onAdRenderFailed");
    }

    @Override
    public void onAdClose() {
    Log.i(TAG, "onAdClose");
    mAdContainer.removeAllViews();
    }
    });
    // 注册完监听后就可以获取原生广告View
    View nativeView = response.getNativeView();
    if (nativeView != null && nativeView.getParent() == null) {
    mAdContainer.removeAllViews();
    mAdContainer.addView(nativeView);
    }

    // 方式二,直接绑定广告容器和曝光点击监听
    response.bindView(mAdContainer, new NativeAdEventListener() {
    @Override
    public void onAdClick() {
    Log.i(TAG, "onAdClick");
    }

    @Override
    public void onADExposed() {
    Log.i(TAG, "onADExposed");
    }

    @Override
    public void onAdRenderFailed(int errorCode) {
    Log.i(TAG, "onAdRenderFailed");
    }

    @Override
    public void onAdClose() {
    Log.i(TAG, "onAdClose");
    mAdContainer.removeAllViews();
    }
    });
    }
  • 在页面的 onDestroy 方法中请调用:

    @Override
    protected void onDestroy() {
    if (mNativeAd != null) {
    mNativeAd.destroy();
    }
    super.onDestroy();
    }

  • PS:完整流程请参考 Demo 中的 com.octopus.sdk.demo.NativeAdActivity 的示例代码。

五、原生(信息流)自渲染广告

5.1、原生自渲染广告接口说明

  • /**
    * 原生广告构造方法
    * @param context 上下文
    * @param adSlotId 广告位id,由运营人员提供
    * @param nativeAdListener 原生广告监听
    */
    public NativeAd(Context context, String adSlotId, NativeAdListener nativeAdListener)

    /**
    * 是否使用SDK内部浏览器打开落地页
    * @param isOpenInNativeBrowser 默认false, true使用SDK内部浏览器打开, false使用本地浏览器打开
    */
    public void openAdInNativeBrowser(boolean isOpenInNativeBrowser)

    /**
    * 广告加载成功后可以获取广告返回价格,单位分
    */
    public int getPrice()

    /**
    * 加载广告
    */
    public void loadAd()

    /**
    * 广告是否加载成功
    * @return true表示加载成功
    */
    public boolean isLoaded()

    /**
    * 广告是否加载成功,并且在有效时间内(有做广告预缓存的用这个)
    * @return true表示加载成功并且有效
    */
    public boolean isValid()

    /**
    * 资源释放
    */
    public void destroy()

5.2、原生自渲染广告回调说明

  • /**
    * 原生广告加载监听器
    */
    NativeAdListener {
    /**
    * 广告加载失败
    * @param errorCode 错误码
    */
    void onAdFailed(int errorCode);

    /**
    * 广告加载成功
    * @param response 原生广告响应数据
    */
    void onAdLoaded(NativeAdResponse response);
    }

    /**
    * 原生广告事件监听器
    */
    NativeAdEventListener {
    /**
    * 广告点击
    */
    void onAdClick();
    /**
    * 广告曝光
    */
    void onADExposed();
    /**
    * 广告渲染失败
    * @param errorCode 错误码
    */
    void onAdRenderFailed(int errorCode);
    /**
    * 广告关闭
    */
    void onAdClose();
    }

5.3、原生自渲染广告响应说明

  • /**
    * 原生广告响应数据
    */
    NativeAdResponse {
    /**
    * 获取广告标题,短文字
    */
    String getTitle();

    /**
    * 获取广告描述,长文字
    */
    String getDescription();

    /**
    * 获取广告按钮文字
    */
    String getButtonText();

    /**
    * 获取 Icon 图片地址
    */
    String getIconUrl();

    /**
    * 获取广告单图图片地址
    */
    String getImageUrl();

    /**
    * 获取图片的地址
    */
    List<String> getImgList();

    /**
    * 获取交互类型
    */
    int getInteractionType();

    /**
    * 获取下载六要素
    */
    ComplianceInfo getComplianceInfo();

    /**
    * 获取下载六要素控件
    */
    View getComplianceView(Context context);

    /**
    * 获取LOGO的Bitmap
    */
    Bitmap getLogo(Context context);

    /**
    * 获取文本LOGO的Bitmap
    */
    Bitmap getTextLogo(Context context);

    /**
    * 获取LOGO的相关信息
    */
    ServerResponse.AdLogoInfo getLogoInfo();

    /**
    * 获取文本LOGO的相关信息
    */
    ServerResponse.AdLogoInfo getTextLogoInfo();

    /**
    * 获取LOGO的链接
    */
    String getLogoUrl();

    /**
    * 获取文本LOGO的链接
    */
    String getTextLogoUrl();

    /**
    * 获取图片的宽度px
    */
    int getPictureWidth();

    /**
    * 获取图片的高度px
    */
    int getPictureHeight();

    /**
    * 判断是不是视频广告
    */
    boolean isVideo();

    /**
    * 获取素材类型
    *
    * @return MaterialType.SINGLE_IMG 或 MaterialType.VIDEO
    */
    int getMaterialType();

    /**
    * 获取视频播放器组件(视频View对象)
    *
    * @return 播放器组件
    */
    View getVideoView(Context context);

    /**
    * 获取高斯模糊组件(图片View对象)
    *
    * @return 高斯模糊组件(图片自适应,不变形)
    */
    View getBlurView(Context context);

    /**
    * 获取原生广告视图
    *
    * @return 原生广告视图
    */
    View getNativeView();

    /**
    * 添加摇一摇
    *
    * @param shakeContainer 用于放置摇一摇的容器
    * @param shakeViewSize 摇一摇控件的宽高 单位dp
    * @param shakeTextSize 摇一摇文案字体大小 单位sp
    */
    void addShakeView(ViewGroup shakeContainer, int shakeViewSize, float shakeTextSize);

    /**
    * 原生模板广告、Banner广告、Draw广告都可以直接设置这个监听,再getNativeView()
    *
    * @param listener 曝光点击事件监听
    */
    void setNativeAdEventListener(NativeAdEventListener listener);

    /**
    * 原生模板广告也可以调用此方法绑定container和事件监听
    * @param adContainer 用于展示广告的容器
    * @param listener 曝光点击事件监听
    */
    void bindView(ViewGroup adContainer, NativeAdEventListener listener);

    /**
    * 原生自渲染广告调用此方法绑定container和事件监听
    * @param adContainer 用于展示广告的容器
    * @param clickViews 可以点击跳转广告的View
    * @param listener 曝光点击事件监听
    */
    void bindUnifiedView(ViewGroup adContainer, List<View> clickViews, NativeAdEventListener listener);

    /**
    * 原生自渲染广告调用此方法绑定container和事件监听
    *
    * @param adContainer 用于展示广告的容器
    * @param clickViews 可以点击跳转广告的View
    * @param closeViews 可以点击关闭广告的View
    * @param listener 曝光点击事件监听
    */
    void bindUnifiedView(ViewGroup adContainer, List<View> clickViews, List<View> closeViews, NativeAdEventListener listener);
    }

5.4、原生自渲染广告示例

  • 创建原生自渲染广告实例:

    mNativeAd = new NativeAd(this, slotId, new NativeAdListener() {

    @Override
    public void onAdFailed(int errorCode) {
    Log.d(TAG, "onAdFailed:" + errorCode);
    Toast.makeText(activity, "onAdFailedToLoad reason: " + errorCode, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onAdLoaded(NativeAdResponse response) {
    Log.d(TAG, "onAdLoaded");
    // 广告是否加载成功并且在有效时间内
    if (mNativeAd != null && mNativeAd.isValid()) {
    unifiedView(response);
    }
    // 注意:竞价结束后记得调用竞胜或竞败接口
    // 竟胜时候调用(提高ECPM, 提升填充率)
    // mNativeAd.sendWinNotice(第二高价格);
    // 竟败时候调用(提高ECPM, 提升填充率)
    // mNativeAd.sendLossNotice(最高价, ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.OTHER);
    }
    });
    //使用SDK内部浏览器打开落地页(默认为false,设为false的情况下会使用本地浏览器打开)
    mNativeAd.openAdInNativeBrowser(true);
    mNativeAd.loadAd();

    //原生自渲染view
    private void unifiedView(NativeAdResponse response) {
    if (response == null) return;
    View unifiedView = LayoutInflater.from(this).inflate(R.layout.item_native_unified_ad_view, null);
    RelativeLayout rlContainer = unifiedView.findViewById(R.id.rl_container);
    FrameLayout adVideo = unifiedView.findViewById(R.id.ad_video);
    ImageView adImage = unifiedView.findViewById(R.id.ad_image);
    ImageView adIcon = unifiedView.findViewById(R.id.ad_icon);
    TextView adTitle = unifiedView.findViewById(R.id.ad_title);
    TextView adDesc = unifiedView.findViewById(R.id.ad_desc);
    Button adButton = unifiedView.findViewById(R.id.ad_button);
    ImageView adLogo = unifiedView.findViewById(R.id.ad_logo);
    ImageView adLogoText = unifiedView.findViewById(R.id.ad_logo_text);
    ImageView adClose = unifiedView.findViewById(R.id.ad_close);
    FrameLayout adCompliance = unifiedView.findViewById(R.id.ad_compliance);

    Log.i("OctopusDemo", TAG
    + "response imageUrl:" + response.getImageUrl()
    + "\n;IconUrl:" + response.getIconUrl()
    + "\n;getTitle:" + response.getTitle()
    + "\n;getDescription:" + response.getDescription()
    + "\n;getButtonText:" + response.getButtonText()
    + "\n;getLogoUrl:" + response.getLogoUrl()
    + "\n;getTextLogoUrl:" + response.getTextLogoUrl()
    );

    // 返回广告的标题
    String title = response.getTitle();
    if (!TextUtils.isEmpty(title)) {
    adTitle.setVisibility(View.VISIBLE);
    adTitle.setText(title);
    }

    // 返回广告的描述文本信息
    String description = response.getDescription();
    if (!TextUtils.isEmpty(description)) {
    adDesc.setVisibility(View.VISIBLE);
    adDesc.setText(description);
    }

    // 返回广告的AppIcon的图片URL
    String iconUrl = response.getIconUrl();
    if (!TextUtils.isEmpty(iconUrl)) {
    // 需要开发者自己处理图片URL,可使用图片加载框架去处理,本示例使用glide加载仅供参考
    Glide.with(this).load(iconUrl).into(adIcon);
    }

    // 判断是否是视频有两种方式,二选一就可以
    if (response.isVideo() || response.getMaterialType() == MaterialType.VIDEO) {
    // 获取视频组件
    View view = response.getVideoView(this);
    if (view != null) {
    // 视频容器背景默认设置为黑色
    adVideo.setBackgroundColor(Color.BLACK);
    // 视频居中展示
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER);
    adVideo.addView(view, layoutParams);
    }
    } else {
    // 图片渲染有两种,一种是直接拿渲染好的高斯模糊组件,防止图片变形
    // 方法一:获取高斯模糊组件
    View view = response.getBlurView(this);
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER);
    adVideo.addView(view, layoutParams);
    // 方法二:自己使用广告返回的图片URL
    String imageUrl = response.getImageUrl();
    if (!TextUtils.isEmpty(imageUrl)) {
    // 需要开发者自己处理图片URL,可使用图片加载框架去处理,本示例使用glide加载仅供参考
    Glide.with(this).load(imageUrl).into(adImage);
    }
    }

    // 返回点击按钮的文本信息
    adButton.setText(response.getButtonText());

    // 请开发者务必自己实现加入sdk的logo及广告字样
    // 返回广告的logoURL
    String logoUrl = response.getLogoUrl();
    if (!TextUtils.isEmpty(logoUrl)) {
    Glide.with(this).load(logoUrl).into(adLogo);
    }
    // 返回广告的文字logoURL
    String textLogoUrl = response.getTextLogoUrl();
    if (!TextUtils.isEmpty(textLogoUrl)) {
    Glide.with(this).load(textLogoUrl).into(adLogoText);
    }

    // 获取交互类型,判断是否是下载广告
    if (response.getInteractionType() == NativeAdResponse.INTERACTION_TYPE_DOWNLOAD) {
    // 获取广告下载六要素
    ComplianceInfo complianceInfo = response.getComplianceInfo();
    // 可以选择自己添加下载六要素
    // 也可以直接添加下载六要素控件
    if (complianceInfo != null) {
    // 下载六要素默认为屏幕宽度
    // View complianceView = response.getComplianceView(this);
    // 下载六要素指定宽度,单位dp,用于缩放文字比例
    View complianceView = response.getComplianceView(this, 360);
    FrameLayout.LayoutParams complianceParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
    adCompliance.addView(complianceView, complianceParams);
    }
    }

    // 添加摇一摇 shakeViewSize:摇一摇控件的宽高,单位dp shakeTextSize 摇一摇文案字体大小,单位sp
    response.addShakeView(rlContainer, 100, 10);

    // 把自定义View添加到广告容器里面
    mAdContainer.removeAllViews();
    mAdContainer.addView(unifiedView);

    // 把允许点击的View添加到集合里面
    ArrayList<View> clickViews = new ArrayList<>();
    clickViews.add(adImage);
    clickViews.add(adButton);
    // 把允许关闭的View添加到集合里面
    ArrayList<View> closeViews = new ArrayList<>();
    closeViews.add(adClose);
    // 注册原生自渲染广告的曝光点击事件,必须调用
    response.bindUnifiedView(mAdContainer, clickViews, closeViews, new NativeAdEventListener() {
    @Override
    public void onAdClick() {
    Log.i(TAG, "onAdClick");
    }

    @Override
    public void onADExposed() {
    Log.i(TAG, "onADExposed");
    }

    @Override
    public void onAdRenderFailed(int errorCode) {
    Log.i(TAG, "onAdRenderFailed");
    Toast.makeText(NativeUnifiedActivity.this, "onAdRenderFailed reason: " + errorCode, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onAdClose() {
    Log.i(TAG, "onAdClose");
    mAdContainer.removeAllViews();
    }
    });
    }
  • R.layout.item_native_unified_ad_view 布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
    android:id="@+id/rl_container"
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <FrameLayout
    android:id="@+id/ad_video"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

    <ImageView
    android:id="@+id/ad_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:adjustViewBounds="true"
    android:contentDescription="@null"
    android:scaleType="fitXY" />

    <FrameLayout
    android:id="@+id/ad_compliance"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

    <ImageView
    android:id="@+id/ad_close"
    android:layout_width="15dp"
    android:layout_height="15dp"
    android:layout_alignParentEnd="true"
    android:layout_margin="5dp"
    android:contentDescription="@null"
    android:src="@drawable/oct_close" />
    </RelativeLayout>

    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp">

    <ImageView
    android:id="@+id/ad_icon"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_centerVertical="true"
    android:adjustViewBounds="true"
    android:contentDescription="@null"
    android:scaleType="fitCenter"
    android:visibility="gone" />

    <Button
    android:id="@+id/ad_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentEnd="true"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:layout_marginEnd="5dp"
    android:layout_marginRight="5dp"
    android:contentDescription="@null"
    android:importantForAccessibility="no" />

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginStart="5dp"
    android:layout_marginLeft="5dp"
    android:layout_toStartOf="@+id/ad_button"
    android:layout_toLeftOf="@+id/ad_button"
    android:layout_toEndOf="@+id/ad_icon"
    android:layout_toRightOf="@+id/ad_icon"
    android:orientation="vertical">

    <TextView
    android:id="@+id/ad_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#000000"
    android:textSize="14sp" />

    <TextView
    android:id="@+id/ad_desc"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    android:textColor="#000000"
    android:textSize="12sp" />
    </LinearLayout>
    </RelativeLayout>

    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginVertical="2dp">

    <ImageView
    android:id="@+id/ad_logo_text"
    android:layout_width="32dp"
    android:layout_height="16dp"
    android:layout_alignParentStart="true"
    android:layout_alignParentLeft="true"
    android:layout_marginStart="5dp"
    android:layout_marginLeft="5dp"
    android:contentDescription="@null"
    android:scaleType="fitCenter" />

    <ImageView
    android:id="@+id/ad_logo"
    android:layout_width="13dp"
    android:layout_height="13dp"
    android:layout_alignParentEnd="true"
    android:layout_alignParentRight="true"
    android:layout_marginEnd="5dp"
    android:layout_marginRight="5dp"
    android:contentDescription="@null"
    android:scaleType="fitCenter" />
    </RelativeLayout>
    </LinearLayout>

  • 在页面的 onDestroy 方法中请调用:

    @Override
    protected void onDestroy() {
    if (mNativeAd != null){
    mNativeAd.destroy();
    }
    super.onDestroy();
    }

  • PS:完整流程请参考 Demo 中的 com.octopus.sdk.demo.NativeUnifiedActivity 的示例代码。

六、Draw(信息流)广告

6.1、Draw 广告接口说明

  • /**
    * Draw广告构造方法
    * @param context 上下文
    * @param adSlotId 广告位id,由运营人员提供
    * @param nativeAdListener Draw广告监听
    */
    public DrawAd(Context context, String adSlotId, DrawAdListener drawAdListener)

    /**
    * 是否使用SDK内部浏览器打开落地页
    * @param isOpenInNativeBrowser 默认false, true使用SDK内部浏览器打开, false使用本地浏览器打开
    */
    public void openAdInNativeBrowser(boolean isOpenInNativeBrowser)

    /**
    * 广告加载成功后可以获取广告返回价格,单位分
    */
    public int getPrice()

    /**
    * 加载广告
    */
    public void loadAd()

    /**
    * 广告是否加载成功
    * @return true表示加载成功
    */
    public boolean isLoaded()

    /**
    * 广告是否加载成功,并且在有效时间内(有做广告预缓存的用这个)
    * @return true表示加载成功并且有效
    */
    public boolean isValid()

    /**
    * 资源释放
    */
    public void destroy()

6.2、Draw 广告回调说明

  • /**
    * Draw广告加载监听器
    */
    DrawAdListener {
    /**
    * 广告加载失败
    * @param errorCode 错误码
    */
    void onAdFailed(int errorCode);

    /**
    * 广告加载成功
    * @param response Draw广告响应数据
    */
    void onAdLoaded(NativeAdResponse response);
    }

    /**
    * Draw广告事件监听器
    */
    NativeAdEventListener {
    /**
    * 广告点击
    */
    void onAdClick();
    /**
    * 广告曝光
    */
    void onADExposed();
    /**
    * 广告渲染失败
    * @param errorCode 错误码
    */
    void onAdRenderFailed(int errorCode);
    /**
    * 广告关闭
    */
    void onAdClose();
    }

6.3、Draw 广告示例

  • 创建 Draw 广告实例:

    mDrawAd = new DrawAd(this, mSlotId, new DrawAdListener() {
    @Override
    public void onAdFailed(int errorCode) {
    Log.i(TAG, "onAdFailed:" + errorCode);
    Toast.makeText(mContext, "onAdFailedToLoad reason: " + errorCode, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onAdLoaded(NativeAdResponse response) {
    Log.i(TAG, "onAdLoaded");
    // 广告是否加载成功并且在有效时间内
    if (mDrawAd != null && mDrawAd.isValid()) {
    List<TestItem.NormalVideo> normalVideoList = getTestVideo();
    for (TestItem.NormalVideo normalVideo : normalVideoList) {
    mDrawList.add(new TestItem(normalVideo, null));
    }
    int random = (int) (Math.random() * 100);
    int index = random % normalVideoList.size();
    if (index == 0) {
    index++;
    }
    mDrawList.add(index, new TestItem(null, response));
    mRecyclerAdapter.notifyDataSetChanged();
    }
    // 注意:竞价结束后记得调用竞胜或竞败接口
    // 竟胜时候调用(提高ECPM, 提升填充率)
    // mDrawAd.sendWinNotice(第二高价格);
    // 竟败时候调用(提高ECPM, 提升填充率)
    // mDrawAd.sendLossNotice(最高价, ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.OTHER);
    }
    });
    // 使用SDK内部浏览器打开落地页(默认为false,设为false的情况下会使用本地浏览器打开)
    mDrawAd.openAdInNativeBrowser(true);
    mDrawAd.loadAd();

    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
    DrawViewHolder drawViewHolder = (DrawViewHolder) viewHolder;
    item.response.setNativeAdEventListener(new NativeAdEventListener() {
    @Override
    public void onAdClick() {
    Log.i(TAG, "onAdClick");
    }

    @Override
    public void onADExposed() {
    Log.i(TAG, "onADExposed");
    }

    @Override
    public void onAdRenderFailed(int errorCode) {
    Log.i(TAG, "onAdRenderFailed");
    }

    @Override
    public void onAdClose() {
    Log.i(TAG, "onAdClose");
    }
    });
    View nativeView = item.response.getNativeView();
    if (nativeView != null && nativeView.getParent() == null) {
    drawViewHolder.mVideoContainer.removeAllViews();
    drawViewHolder.mVideoContainer.addView(nativeView);
    }
    }
  • 在页面的 onDestroy 方法中请调用:

    @Override
    protected void onDestroy() {
    if (mDrawAd != null) {
    mDrawAd.destroy();
    }
    super.onDestroy();
    }

  • PS:完整流程请参考 Demo 中的 com.octopus.sdk.demo.DrawActivity 的示例代码。

七、插屏广告

7.1、插屏广告接口说明

  • /**
    * 插屏广告构造函数
    * @param context 上下文
    * @param adSlotId 广告位id,由运营人员提供
    * @param adListener 插屏广告监听
    */
    public InterstitialAd(Context context, String adSlotId, InterstitialAdListener adListener)

    /**
    * 是否使用SDK内部浏览器打开落地页
    * @param isOpenInNativeBrowser 默认false, true使用SDK内部浏览器打开, false使用本地浏览器打开
    */
    public void openAdInNativeBrowser(boolean isOpenInNativeBrowser)

    /**
    * 广告是否加载成功
    * @return true表示加载成功
    */
    public boolean isLoaded()

    /**
    * 广告是否加载成功,并且在有效时间内(有做广告预缓存的用这个)
    * @return true表示加载成功并且有效
    */
    public boolean isValid()

    /**
    * 广告加载
    */
    public void loadAd()

    /**
    * 广告加载成功后可以获取广告返回价格,单位分
    */
    public int getPrice()

    /**
    * 广告展示
    */
    public void show(Activity activity)

    /**
    * 资源释放
    */
    public void destroy()

7.2、插屏广告回调说明

  • /**
    * 插屏广告监听器
    */
    InterstitialAdListener {
    /**
    * 广告加载失败
    * @param errorCode 错误码
    */
    void onAdFailedToLoad(int errorCode);

    /**
    * 广告加载成功
    */
    void onAdLoaded();

    /**
    * 素材缓存完成
    * @param isSuccess 是否缓存成功
    */
    void onAdCacheLoaded(boolean isSuccess);

    /**
    * 广告展示
    */
    void onAdShown();

    /**
    * 广告关闭
    */
    void onAdClosed();

    /**
    * 广告点击
    */
    void onAdClick();
    }

7.3、插屏广告示例

  • 创建插屏广告实例:

    mInterstitialAd = new InterstitialAd(this, slotId, new InterstitialAdListener() {
    @Override
    public void onAdClosed() {
    Log.i(TAG, "onAdClosed");
    }

    @Override
    public void onAdClicked() {
    Log.i(TAG, "onAdClicked");
    }

    @Override
    public void onAdFailedToLoad(int errorCode) {
    Log.i(TAG, "onAdFailedToLoad");
    }

    @Override
    public void onAdShown() {
    Log.i(TAG, "onAdShown");
    }

    @Override
    public void onAdLoaded() {
    Log.i(TAG, "onAdLoaded");
    // 广告在此竞价 mInterstitialAd.getPrice(); 单位分
    // 注意:竞价结束后记得调用竞胜或竞败接口
    // 竟胜时候调用(提高ECPM, 提升填充率)
    // mInterstitialAd.sendWinNotice(第二高价格);
    // 竟败时候调用(提高ECPM, 提升填充率)
    // mInterstitialAd.sendLossNotice(最高价, ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.OTHER);
    }

    @Override
    public void onAdCacheLoaded(boolean isSuccess) {
    Log.i(TAG, "onAdCacheLoaded: " + isSuccess);
    // 图片素材和视频资源缓存到本地的回调,在此展示效果最好.
    // 注意:视频等资源缓存失败会回调onAdFailedToLoad
    // isSuccess可以用来判断是否缓存成功,没缓存成功也可以播放在线视频
    showInterstitial();
    }
    });

    // 使用SDK内部浏览器打开落地页(默认为false,设为false的情况下会使用本地浏览器打开)
    mInterstitialAd.openAdInNativeBrowser(true);
    mInterstitialAd.loadAd();

    // 展示插屏广告
    private void showInterstitial() {
    // 广告是否加载成功并且在有效时间内
    if (mInterstitialAd != null && mInterstitialAd.isValid()) {
    mInterstitialAd.show(InterstitialActivity.this);
    }
    }
  • 在页面的 onDestroy 方法中请调用:

    @Override
    protected void onDestroy() {
    if (mInterstitialAd != null){
    mInterstitialAd.destroy();
    }
    super.onDestroy();
    }

  • PS: 完整流程请参考 Demo 中的 com.octopus.sdk.demo.InterstitialActivity 的示例代码。

八、全屏视频广告

8.1、全屏视频广告接口说明

  • /**
    * 全屏视频广告构造函数
    * @param context 上下文
    * @param adSlotId 广告位id,由运营人员提供
    * @param adListener 全屏视频广告监听
    */
    public FullScreenVideoAd(Context context, String adSlotId, FullScreenVideoAdListener adListener)

    /**
    * 是否使用SDK内部浏览器打开落地页
    * @param isOpenInNativeBrowser 默认false, true使用SDK内部浏览器打开, false使用本地浏览器打开
    */
    public void openAdInNativeBrowser(boolean isOpenInNativeBrowser)

    /**
    * 广告是否加载成功
    * @return true表示加载成功
    */
    public boolean isLoaded()

    /**
    * 广告是否加载成功,并且在有效时间内(有做广告预缓存的用这个)
    * @return true表示加载成功并且有效
    */
    public boolean isValid()

    /**
    * 广告加载
    */
    public void loadAd()

    /**
    * 广告加载成功后可以获取广告返回价格,单位分
    */
    public int getPrice()

    /**
    * 广告展示
    */
    public void show(Activity activity)

    /**
    * 资源释放
    */
    public void destroy()

8.2、全屏视频广告回调说明

  • /**
    * 全屏视频广告监听器
    */
    FullScreenVideoAdListener {
    /**
    * 广告加载失败
    * @param errorCode 错误码
    */
    void onAdFailedToLoad(int errorCode);

    /**
    * 广告加载成功
    */
    void onAdLoaded();

    /**
    * 素材缓存完成
    * @param isSuccess 是否缓存成功
    */
    void onAdCacheLoaded(boolean isSuccess);

    /**
    * 广告展示
    */
    void onAdShown();

    /**
    * 广告关闭
    */
    void onAdClosed();

    /**
    * 广告点击
    */
    void onAdClick();
    }

8.3、全屏视频广告示例

  • 创建全屏视频广告实例:

    mFullScreenVideoAd = new FullScreenVideoAd(this, mSlotId, new FullScreenVideoAdListener() {
    @Override
    public void onAdClosed() {
    Log.i(TAG, "onAdClosed");
    }

    @Override
    public void onAdClicked() {
    Log.i(TAG, "onAdClicked");
    }

    @Override
    public void onAdFailedToLoad(int errorCode) {
    Log.i(TAG, "onAdFailedToLoad" + errorCode);
    }

    @Override
    public void onAdShown() {
    Log.i(TAG, "onAdShown");
    }

    @Override
    public void onAdLoaded() {
    Log.i(TAG, "onAdLoaded");
    // 广告在此竞价 mFullScreenVideoAd.getPrice(); 单位分
    // 注意:竞价结束后记得调用竞胜或竞败接口
    // 竟胜时候调用(提高ECPM, 提升填充率)
    // mFullScreenVideoAd.sendWinNotice(第二高价格);
    // 竟败时候调用(提高ECPM, 提升填充率)
    // mFullScreenVideoAd.sendLossNotice(最高价, ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.OTHER);
    }

    @Override
    public void onAdCacheLoaded(boolean isSuccess) {
    Log.i(TAG, "onAdCacheLoaded: " + isSuccess);
    // 图片素材和视频资源缓存到本地的回调,在此展示效果最好.
    // 注意:视频等资源缓存失败会回调onAdFailedToLoad
    // isSuccess可以用来判断是否缓存成功,没缓存成功也可以播放在线视频
    showFullScreenVideo();
    }
    });
    // 使用SDK内部浏览器打开落地页(默认为false,设为false的情况下会使用本地浏览器打开)
    mFullScreenVideoAd.openAdInNativeBrowser(true);
    mFullScreenVideoAd.loadAd();

    // 展示全屏视频广告
    private void showFullScreenVideo() {
    // 广告是否加载成功并且在有效时间内
    if (mFullScreenVideoAd != null && mFullScreenVideoAd.isValid()) {
    mFullScreenVideoAd.show(FullScreenVideoActivity.this);
    }
    }
  • 在页面的 onDestroy 方法中请调用:

    @Override
    protected void onDestroy() {
    if (mFullScreenVideoAd != null) {
    mFullScreenVideoAd.destroy();
    }
    super.onDestroy();
    }

  • PS: 完整流程请参考 Demo 中的 com.octopus.sdk.demo.FullScreenVideoActivity 的示例代码。

九、激励视频

9.1、激励视频接口说明

  • /**
    * 激励视频广告构造函数
    * @param context 上下文
    * @param slotId 广告位id,由运营人员提供
    * @param listener 激励视频广告监听
    */
    public RewardVideoAd(Context context, String slotId, RewardVideoAdListener listener)

    /**
    * 是否使用SDK内部浏览器打开落地页
    * @param isOpenInNativeBrowser 默认false, true使用SDK内部浏览器打开, false使用本地浏览器打开
    */
    public void openAdInNativeBrowser(boolean isOpenInNativeBrowser)

    /**
    * 广告加载
    */
    public void loadAd()

    /**
    * 广告是否加载成功
    * @return true表示加载成功
    */
    public boolean isLoaded()

    /**
    * 广告是否加载成功,并且在有效时间内(有做广告预缓存的用这个)
    * @return true表示加载成功并且有效
    */
    public boolean isValid()

    /**
    * 广告加载成功后可以获取广告返回价格,单位分
    */
    public int getPrice()

    /**
    * 广告展示
    */
    public void show(Activity activity)

    /**
    * 服务端验证可以传入开发者⾃定义的附加参数
    */
    public void setExtraData(String extraData)

    /**
    * 服务端验证可以传入开发者系统中的⽤户id
    */
    public void setUserId(String userId)

    /**
    * 激励视频暂停
    */
    public void pause()

    /**
    * 激励视频恢复
    */
    public void resume()

    /**
    * 资源释放
    */
    public void destroy()

9.2、激励视频回调说明

  • /**
    * 激励视频广告监听器
    */
    RewardVideoAdListener {

    /**
    * 获得奖励,在该回调中做奖励操作
    */
    void onRewarded(RewardItem reward);

    /**
    * 广告加载失败
    */
    void onRewardVideoAdFailedToLoad(int errorCode);

    /**
    * 广告加载成功
    */
    void onRewardVideoAdLoaded();

    /**
    * 素材缓存完成
    * @param isSuccess 是否缓存成功
    */
    void onRewardVideoCached(boolean isSuccess);

    /**
    * 广告曝光展示
    */
    void onRewardVideoAdShown();

    /**
    * 广告关闭
    */
    void onRewardVideoAdClosed();

    /**
    * 广告点击
    */
    void onRewardVideoAdClicked();

    /**
    * 广告播放完成
    */
    oid onRewardVideoAdComplete();
    }

9.3、激励视频示例

  • 创建激励视频实例:

    // 加载广告 注意:每次加载的时候都要new一个RewardVideoAd,防止重复同一个广告
    private void loadRewardVideo() {
    mRewardVideoAd = new RewardVideoAd(this, slotId, new RewardVideoAdListener() {
    @Override
    public void onRewarded(RewardItem reward) {
    Log.d(TAG, "onRewarded:" + reward.getAmount() + "==" + reward.getType());
    // 完成激励视频观看时长任务
    }

    @Override
    public void onRewardVideoAdClosed() {
    Log.d(TAG, "onRewardVideoAdClosed");
    // 激励视频关闭或者跳过
    }

    @Override
    public void onRewardVideoAdShown() {
    Log.d(TAG, "onRewardVideoAdShown");
    // 激励视频曝光
    }

    @Override
    public void onRewardVideoAdFailedToLoad(int errorCode) {
    Log.d(TAG, "onRewardVideoAdFailedToLoad:" + errorCode);
    // 广告加载失败或者视频播放失败
    }

    @Override
    public void onRewardVideoAdLoaded() {
    Log.d(TAG, "onRewardVideoAdLoaded");
    // 广告加载成功,可以直接展示激励视频
    // 视频广告的素材加载完毕,比如视频url等,在此回调后,如果视频没缓存过,会播放在线视频,网络不好可能出现加载缓冲,影响体验。
    // 注意:竞价结束后记得调用竞胜或竞败接口
    // 竟胜时候调用(提高ECPM, 提升填充率)
    // mRewardVideoAd.sendWinNotice(第二高价格);
    // 竟败时候调用(提高ECPM, 提升填充率)
    // mRewardVideoAd.sendLossNotice(最高价, ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.OTHER);
    }

    @Override
    public void onRewardVideoCached(boolean isSuccess) {
    Log.i(TAG, "onAdRewardVideoCached: " + isSuccess);
    // 视频广告加载后,视频资源缓存到本地的回调,在此回调后,播放本地视频,流畅不阻塞。
    // isSuccess可以用来判断是否缓存成功,没缓存成功也可以播放在线视频
    showRewardVideo();
    }

    @Override
    public void onRewardVideoAdClicked() {
    Log.d(TAG, "onRewardVideoAdClicked");
    // 激励视频有点击
    }

    @Override
    public void onRewardVideoAdComplete() {
    Log.d(TAG, "onRewardVideoAdComplete");
    // 激励视频播放完成
    }
    });
    // 使用SDK内部浏览器打开落地页(默认为false,设为false的情况下会使用本地浏览器打开)
    mRewardVideoAd.openAdInNativeBrowser(true);
    mRewardVideoAd.loadAd();
    }

    // 展示激励视频
    private void showRewardVideo() {
    if (mRewardVideoAd != null && mRewardVideoAd.isValid()) {
    mRewardVideoAd.show();
    }
    }
  • 在页面的 onPause(),onResume(),onDestroy 方法中请调用:

    @Override
    public void onPause() {
    super.onPause();
    mRewardVideoAd.pause();
    }

    @Override
    public void onResume() {
    super.onResume();
    mRewardVideoAd.resume();
    }

    @Override
    protected void onDestroy() {
    if (mRewardedVideoAd != null){
    mRewardedVideoAd.destroy();
    }
    super.onDestroy();
    }

服务端回调说明

9.4、服务端回调说明

章鱼广告 SDK 服务器会拿到后台配置的服务器回调链接,并拼接以下参数进行回传:

slotId=%s&appId=%s&transId=%s&userId=%s&extrai=%s&sign=%s&name=%s&count=%s
字段定义字段名称字段类型备注
slotId签名后的广告位 IDstring签名后的广告位 ID,需要可校验
appIdAPP IDstring应用 ID,需要可校验
transId交易 idstring完成观看的唯一交易 ID
sign签名后的 transIdstring必须验证的签名信息
userId用户 idstring调用 SDK 传入并透传,应用对用户的唯一标识,如无需要则为空
extra其他信息string调用 SDK 传入并透传,如无需要则为空
name奖品名称string需要就联系运营配置,如无需要则为空
count奖品数量string需要就联系运营配置,如无需要则为空

具体示例:

http://开发者回调地址/sdk/callback?slotId=%s&appId=%s&transId=%s&userId=%s&extra=%s&sign=%s&name=%s&count=%s

9.5、服务端验证说明

当选择需要服务端验证时,开发者需要按照以上接口进行开发,并向运营提供回调 URL 让运营帮忙配置一下回调 URL。服务端回调是指在用户看完视频达到奖励条件时,章鱼广告 SDK 服务端会向开发者服务端发送一个验证请求,同时客户端会给出 onReward 回调,开发者根据回调进行奖励发放,因为奖励回调和服务端验证请求是同时发送的,开发者后台收到验证请求可能会有延迟或网络原因上的失败,开发者需要平衡用户体验与奖励验证。

补充: 章鱼广告 SDK 后台向上述 URL 发起请求后,您会在服务端收到某个 transId 的请求,如果签名验证正确,那么此 transId 对应的曝光为有效曝光

签名生成方式:

sign = sha256(transid:secret)

其中 transId 为交易 id,secret 运营配置服务端 URL 时获取到的密钥,配置好后跟运营要。

9.6、约定返回参数

字段名称字段定义字段类型备注
isValid校验结果bool判定结果,是否发放奖励

注意:按照 SDK 要求需要服务器判断的回调 url 是一个 get 请求默认返回的是一个 json 字符串{"isValid": true}

示例:

{
"isValid": true
}
  • PS:完整流程请参考 Demo 中的 com.octopus.sdk.demo.RewardVideoActivity 的示例代码。

十、横幅广告

10.1、Banner 广告接口说明

  • /**
    * Banner广告构造函数
    * @param context 上下文
    * @param adSlotId 广告位id,由运营人员提供
    * @param adListener Banner广告监听
    */
    public BannerAd(Context context, String adSlotId, BannerAdListener adListener)

    /**
    * 是否使用SDK内部浏览器打开落地页
    * @param isOpenInNativeBrowser 默认false, true使用SDK内部浏览器打开, false使用本地浏览器打开
    */
    public void openAdInNativeBrowser(boolean isOpenInNativeBrowser)

    /**
    * 广告是否加载成功
    * @return true表示加载成功
    */
    public boolean isLoaded()

    /**
    * 广告是否加载成功,并且在有效时间内(有做广告预缓存的用这个)
    * @return true表示加载成功并且有效
    */
    public boolean isValid()

    /**
    * 广告加载
    */
    public void loadAd()

    /**
    * 广告加载成功后可以获取广告返回价格,单位分
    */
    public int getPrice()

    /**
    * 广告展示
    */
    public void show()

    /**
    * 资源释放
    */
    public void destroy()

10.2、Banner 广告回调说明

  • /**
    * Banner广告监听器
    */
    BannerAdListener {
    /**
    * 广告加载失败
    * @param errorCode 错误码
    */
    void onAdFailed(int errorCode);

    /**
    * 广告加载成功
    * @param response 原生广告响应数据
    */
    void onAdLoaded(NativeAdResponse response);
    }

    /**
    * Draw广告事件监听器
    */
    NativeAdEventListener {
    /**
    * 广告点击
    */
    void onAdClick();
    /**
    * 广告曝光
    */
    void onADExposed();
    /**
    * 广告渲染失败
    * @param errorCode 错误码
    */
    void onAdRenderFailed(int errorCode);
    /**
    * 广告关闭
    */
    void onAdClose();
    }

10.3、Banner 广告示例

  • 创建 Banner 广告实例:

    mBannerAd = new BannerAd(context, mSlotId, new BannerAdListener() {
    @Override
    public void onAdFailed(int errorCode) {
    Log.i(TAG, "onAdFailed:" + errorCode);
    }

    @Override
    public void onAdLoaded(NativeAdResponse response) {
    Log.i(TAG, "onAdLoaded");
    // 广告是否加载成功并且在有效时间内
    if (mBannerAd != null && mBannerAd.isValid()) {
    int adWidth = ViewUtil.getScreenWidth(context);
    // 设置广告的宽度单位px(防止SDK获取不到容器的宽度)
    response.setAdWidth(adWidth);
    showBannerAd(response);
    }
    // 广告在此竞价 mBannerAd.getPrice(); 单位分
    // 注意:竞价结束后记得调用竞胜或竞败接口
    // 竟胜时候调用(提高ECPM, 提升填充率)
    // mBannerAd.sendWinNotice(第二高价格);
    // 竟败时候调用(提高ECPM, 提升填充率)
    // mBannerAd.sendLossNotice(最高价, ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.OTHER);
    }
    });
    // 使用SDK内部浏览器打开落地页(默认为false,设为false的情况下会使用系统浏览器打开)
    mBannerAd.openAdInNativeBrowser(true);
    mBannerAd.loadAd();


  • 把 Banner 添加到广告容器中:

    public void showBannerAd(NativeAdResponse response) {
    if (response == null) return;
    response.setNativeAdEventListener(new NativeAdEventListener() {
    @Override
    public void onAdClick() {
    Log.i(TAG, "onAdClick");
    }

    @Override
    public void onADExposed() {
    Log.i(TAG, "onADExposed");
    }

    @Override
    public void onAdRenderFailed(int errorCode) {
    Log.i(TAG, "onAdRenderFailed");
    }

    @Override
    public void onAdClose() {
    Log.i(TAG, "onAdClose");
    mAdContainer.removeAllViews();
    }
    });
    // 注册完监听后就可以获取Banner广告View
    View nativeView = response.getNativeView();
    if (nativeView != null && nativeView.getParent() == null) {
    mAdContainer.removeAllViews();
    mAdContainer.addView(nativeView);
    }
    }
  • 在页面的 onDestroy 方法中请调用:

    @Override
    protected void onDestroy() {
    if (mBannerAd != null){
    mBannerAd.destroy();
    }
    super.onDestroy();
    }

  • PS: 完整流程请参考 Demo 中的 com.octopus.sdk.demo.BannerActivity 的示例代码。

十一、竞胜竞败回传(媒体 RTB 时调用,提高 ECPM 出价)

  • 说明:章鱼广告平台根据媒体传回来的竞胜竞败价格,通过相应算法自动提高出价来获得广告曝光,媒体 RTB 时一定要调用,否则会导致价格出不上去。

  • 示例:

    splashAd.sendWinNotice(1000); // 价格传竞价第二高价格
    splashAd.sendLossNotice(100,ADBidEvent.PRICE_LOW_FILTER,ADBidEvent.CSJ); // 价格传竞价最高的价格

​ 11.1 接口说明**

  • IBidding 接口说明

    方法名含义
    sendWinNotice(int secondWinPrice);竞价成功时上报接口 secondWinPrice 竞价第二名价格,单位是分 (非必填)
    sendLossNotice(int winPrice, String lossReason, String winBidder);竞价失败时上报接口 winPrice 胜出者价格 单位分(非必填) lossReason 竞价失败原因(非必填) winBidder 胜出者 (非必填) 枚举值如下
  • ADBidEvent

    public class ADBidEvent {
    /**
    * 竞价失败原因
    * 1001 底价过滤
    * 1002 bid价格低于最高价
    * 1003 素材黑名单过滤
    * 1004 竞品过滤
    * 1005 超时过滤
    * 1006 其它过滤
    */
    public static final String BID_PRICE_FILTER = "1001";
    public static final String PRICE_LOW_FILTER = "1002";
    public static final String ADM_BLACKLIST_FILTER = "1003";
    public static final String COMPETE_FILTER = "1004";
    public static final String TIMEOUT_FILTER = "1005";
    public static final String OTHER_FILTER = "1006";

    /**
    * 竞价胜出者
    * CSJ 穿山甲/头条
    * GDT 优量汇/广点通
    * KUAISHOU 快手
    * BAIDU 百青藤/百度
    * SIGMOB sigmob
    * OPPO oppo
    * VIVO vivo
    * HUAWEI 华为
    * XIAOMI 小米
    * JD 京东
    * QM 趣盟
    * ONEWAY 万唯
    * OTHER 其他家
    */
    public static final String CSJ = "CSJ";
    public static final String GDT = "GDT";
    public static final String KUAISHOU = "KUAISHOU";
    public static final String BAIDU = "BAIDU";
    public static final String SIGMOB = "SIGMOB";
    public static final String OPPO = "OPPO";
    public static final String VIVO = "VIVO";
    public static final String HUAWEI = "HUAWEI";
    public static final String XIAOMI = "XIAOMI";
    public static final String OCTOPUS = "OCTOPUS";
    public static final String JINGDONG = "JD";
    public static final String QUMENG = "QM";
    public static final String ONEWAY = "ONEWAY";
    public static final String OTHER = "OTHER";
    }

十二、Topon(Taku)平台接入广告 SDK 文档

  • Topon(Taku)自定义广告接入地址:https://help.takuad.com/docs/4M5AIa

  • 12.1 自定义广告源 adapter 参数

    参数填写:{"app_id":"应用 ID","slot_id":"广告位 ID","is_unified":"是否是自渲染 1:是 0 否"}

    广告类型广告类名称Topon 配置参数
    开屏com.octopus.ad.topon.OctopusATSplashAdapter{"app_id":"应用 ID","slot_id":"广告位 ID"}
    插屏com.octopus.ad.topon.OctopusATInterstitialAdapter{"app_id":"应用 ID","slot_id":"广告位 ID"}
    激励视频com.octopus.ad.topon.OctopusATRewardVideoAdapter{"app_id":"应用 ID","slot_id":"广告位 ID"}
    原生模板com.octopus.ad.topon.OctopusATNativeAdapter{"app_id":"应用 ID","slot_id":"广告位 ID","is_unified":"0"}
    原生自渲染com.octopus.ad.topon.OctopusATNativeAdapter{"app_id":"应用 ID","slot_id":"广告位 ID","is_unified":"1"}
    横幅com.octopus.ad.topon.OctopusATBannerAdapter{"app_id":"应用 ID","slot_id":"广告位 ID"}
  • 12.2 添加广告平台1

  • 12.3 创建广告源2

十三、GroMore(融合)聚合平台自定义广告接入文档

有需要可以找 SDK 开发者索要 aar 文件

添加:octopus_gromore_rh_adapter.aar 文件

自定义广告源 adapter 参数

广告类型广告类名称
初始化com.octopus.ad.gromore.OctopusInit
开屏com.octopus.ad.gromore.OctopusSplashLoader
插屏com.octopus.ad.gromore.OctopusInterstitialLoader
激励视频com.octopus.ad.gromore.OctopusRewardLoader
原生com.octopus.ad.gromore.OctopusNativeLoader
横幅com.octopus.ad.gromore.OctopusBannerLoader

13.1 添加广告平台

2

十四、Tobid 聚合平台自定义广告接入文档

有需要可以找 SDK 开发者索要 aar 文件

添加:windmill-octopus-adapter.aar 文件

自定义广告源 adapter 参数

广告类型广告类名称
初始化com.windmill.octopus.OctopusAdapterProxy
开屏com.windmill.octopus.OctopusSplashAdapter
插屏com.windmill.octopus.OctopusInterstitialAdapter
激励视频com.windmill.octopus.OctopusRewardAdapter
原生com.windmill.octopus.OctopusNativeAdapter
横幅com.windmill.octopus.OctopusBannerAdapter

应用维度参数的 key 填 appId,注意大小写。