‹ Appnext Doc Home

Appnext 集成指南

For the C++ version of cocos2d-x v3.x - (all other versions)

集成

首先,您必须到 Appnext 注册并配置好您的应用。

第二,用如下命令来集成 SDKBOX AdColony 插件,请确保您可以正常执行的 SDKBOX 安装器.

$ sdkbox import appnext

重点注意事项

如果您升级到了 Xcode7, 则需要以下额外步骤来确保插件工作正常:

禁用应用程序安全传输策略

添加以下项到 plist:

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

添加后的文件内容看起来就像这样:

禁止 Bitcode 支持

您必须禁止 Bitcode 的支持,否则将会编译失败。

游戏全屏配置

如果您的游戏不同时支持横竖屏,则必须在 Xcode 中选中 Requires full screen,否则将不会通过 Apple 的审核。

canOpenURL 白名单

取决于您使用哪些插件。需要在 info.plistLSApplicationQueriesSchemes 下添加名单。

关于 Creator 工程

Creator 导出工程会修改工程的配置, 这可能会影响 SDKBox 对工程的配置修改. 所以可以有以下做法(任选其一):

  1. 保存导出工程中的修改, 对于 SDKBox 来说可能有这些文件(mk, gradle, gradle.properties, AppDelegate.cpp, ...), 导出后再恢复对应该文件
  2. 在每一次 Creator 导出工程后, 重新 import 插件.

推荐第一种, 但是第一种的麻烦点在于, 对于第一次(或很久没接触的人)可能会有露掉某个文件 第二种, 很方便, 它的麻烦点在于, 如果你对工程有自己的修改, SDKBox 的重新 import 不能帮你恢复.

JSON 配置

SDKBOX 安装器会自动在您的工程中添加一个样例配置文件sdkbox_config.json.在您编译工程前,请修改里面的参数,用您自己的应用信息

可选配置

更多信息请参考以下链接:

例子:


{
    "ios": {
        "Appnext":{
            "debug":true,
            "ads": {
                "default": {
                    "cache":true,
                    "id":"6d596bc5-b4c1-48ca-be95-3758fd29a3a5",
                    "type":"interstitial"
                }
            }
        }
    },
    "android": {
        "Appnext":{
            "debug":true,
            "ads": {
                "default": {
                    "cache":true,
                    "id":"2f6850dd-190a-499d-aa50-1f4a3dd1ed5f",
                    "type":"interstitial",

                    "button_text":"Button Text",
                    "button_color":"#6AB344",
                    "categories":"Action,Puzzle",
                    "postback":"postback",
                    "can_close":false,

                    "skip_text":"Skip Text",
                    "mute":false,
                    "autoplay":true,
                    "creative_type":"managed"
                },
                "fullscreen": {
                    "cache":true,
                    "id": "17322152-1ef3-4e72-9677-eaf7c09f1054",
                    "type": "fullscreen",

                    "button_text":"Button Text",
                    "button_color":"#6AB344",
                    "categories":"Action,Puzzle",
                    "postback":"postback",
                    "can_close":false,

                    "progress_type":"clock",
                    "progress_color":"#ffffff",
                    "show_close_button":true,
                    "video_lenght":"short"
                },
                "reward": {
                    "cache":true,
                    "id": "8d653a16-129b-4c14-bd22-fae625f70cf4",
                    "type": "reward",

                    "button_text":"Button Text",
                    "button_color":"#6AB344",
                    "categories":"Action,Puzzle",
                    "postback":"postback",
                    "can_close":false,

                    "progress_type":"bar",
                    "progress_color":"#ffff00",
                    "show_close_button":false,
                    "video_lenght":"long"
                }
            }
        }
    }
}

使用

初始化 Appnext

#include "PluginAppnext/PluginAppnext.h"
AppDelegate::applicationDidFinishLaunching()
{
     sdkbox::PluginAppnext::init();
}

缓存插屏或者视频广告

sdkbox::PluginAppnext::cacheAd("default");
sdkbox::PluginAppnext::cacheVideo("fullscreen");

注意 : Appnext 的广告需要先缓存,再使用。

刷新插屏或者视频广告

sdkbox::PluginAppnext::refreshAds();
sdkbox::PluginAppnext::refreshVideo("fullscreen");

NOTE : 您需要在一个广告关闭时刷新它,否则下次不会显示广告。

显示插屏或者视频广告

sdkbox::PluginAppnext::showAd("default");
sdkbox::PluginAppnext::showVideo("fullscreen");

隐藏插屏广告

sdkbox::PluginAppnext::hideAd();

检查插屏或者视屏广告是否可以播放

sdkbox::PluginAppnext::isAdReady();
sdkbox::PluginAppnext::isVideoReady("fullscreen");

接受 AppnextListner 事件 (可选)

#include "PluginAppnext/PluginAppnext.h"
class MyClass : public sdkbox::AppnextListener
{
private:
    void onAdError(const std::string& msg) {}
    void onAdLoaded() {}
    void onAdOpened() {} // android 上没有回调
    void onAdClosed() {}
    void onAdClicked() {}

    void onVideoLoaded(const std::string& name) {} // ios 上没有回调
    void onVideoClicked(const std::string& name) {} // ios 上没有回调
    void onVideoClosed(const std::string& name) {} // ios 上没有回调
    void onVideoEnded(const std::string& name) {} // ios 上没有回调
    void onVideoError(const std::string& name, const std::string& msg) {} // ios 上没有回调
}

API Reference

Methods

static bool init ( ) ;

initialize the plugin instance.

static void setListener ( AppnextListener * listener ) ;

Set listener to listen for appnext events

static AppnextListener * getListener ( ) ;

Get the listener

static void removeListener ( ) ;

Remove the listener, and can't listen to events anymore

static void hideAd ( ) ;

Hide advertisement

static void showAd ( ) ;

Show advertisement

static void refreshAds ( ) ;

Refresh advertisement

static void cacheAd ( const std::string & name ) ;

Cache advertisement

static bool isAdReady ( ) ;

Check if advertisement is ready

static void cacheVideo ( const std::string & name ) ;

Cache video with @name

static void showVideo ( const std::string & name ) ;

show video with @name

static void refreshVideo ( const std::string & name ) ;

Refresh video with @name

static bool isVideoReady ( const std::string & name ) ;

Check if video is ready with @name

static void setRewardsTransactionId ( const std::string & transactionId ) ;

Set reward video transaction id

static void setRewardsUserId ( const std::string & userId ) ;

Set reward video user id

static void setRewardsRewardTypeCurrency ( const std::string & currency ) ;

Set type of reward, such as life / credit / points.

static void setRewardsAmountRewarded ( const std::string & amount ) ;

Set the amount of currency that was rewarded.

static void setRewardsCustomParameter ( const std::string & parameter ) ;

Set reward video custom parameter.

Listeners

void onAdError ( const std::string & msg )
void onAdLoaded ( )
void onAdOpened ( )
void onAdClosed ( )
void onAdClicked ( )
void onVideoLoaded ( const std::string & name )
void onVideoClicked ( const std::string & name )
void onVideoClosed ( const std::string & name )
void onVideoEnded ( const std::string & name )
void onVideoError ( const std::string & name , const std::string & msg )

手动集成

如果 SDKBOX 安装器 安装插件失败了,那么需要手动集成插件.如果安装器安装插件成功了,那么不需要,也没必要,按文档再手动集成一次.

下面列出的的步骤一般很少用到.如果你按下面的步骤完成了集成,请在完成集成后,再按步骤检查一次.

Manual Integration For iOS

拖拽下列 framework 从 Appnext 插件包的 plugins/ios 目录到您的 Xcode 工程中,在添加 frameworks 的时候,请勾选 Copy items if needed

sdkbox.framework

PluginAppnext.framework

上面的 frameworks 依赖于大量其他 frameworks。如果您没有添加它们,您也需要添加下列这些系统 frameworks:

AdSupport.framework

SystemConfiguration.framework

Android 手动集成

SDKBox 支持三种 Android 工程, command-line, eclipseAndroid Studio.

Android 平台手动集成

拷贝文件

从插件安装包中的 plugin/android/libs 目录拷贝下列 jar 文件到您的工程的 proj.android/libs 目录。

拷贝 jni 库

plugin/android/jni/ 拷贝并覆盖 <your_project_root>/jni/ 目录.

编辑 AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

在接近文件底部的位置,拷贝并且粘贴下列3个 activity 定义到 application tags 标签结尾处。

<service android:name="com.appnext.core.DownloadService" />
<activity android:name="com.appnext.ads.interstitial.InterstitialActivity"
  android:hardwareAccelerated="true" android:configChanges="keyboardHidden|orientation|screenSize"
  android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
<activity android:name="com.appnext.ads.fullscreen.FullscreenActivity"
  android:hardwareAccelerated="true" android:configChanges="keyboardHidden|orientation|screenSize"
  android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />

编辑 Android.mk

编辑 <project_root>/jni/Android.mk

LOCAL_STATIC_LIBRARIES 添加额外的库:

LOCAL_WHOLE_STATIC_LIBRARIES += PluginAppnext
LOCAL_WHOLE_STATIC_LIBRARIES += sdkbox

在所有 import-module 语句之前添加一条 call 语句:

$(call import-add-path,$(LOCAL_PATH))

在最后添加额外的 import-module 语句:

$(call import-module, ./sdkbox)
$(call import-module, ./pluginappnext)

这意味着您的语句顺序看起来像是这样:

$(call import-add-path,$(LOCAL_PATH))
$(call import-module, ./sdkbox)
$(call import-module, ./pluginappnext)

Note: 如果您使用的是 cocos2d-x 预编译库,那么保证这些语句在已有的 $(call import-module,./prebuilt-mk) 语句之上非常重要。

编辑 Application.mk (只限 Cocos2d-x v3.0 到 v3.2 版本)

编辑 proj.android/jni/Application.mk 保证 APP_STL 的定义正确。如果 Application.mk 包含了 APP_STL := c++_static 语句,那么这条语句应该被改为:

APP_STL := gnustl_static

修改 AppActivity.java

插件版本 >= 2.4.0.3

  1. 找到 AppActivity.java 文件
find . -name "AppActivity.java"
  1. extends Cocos2dxActivity 替换为 extends com.sdkbox.plugin.SDKBoxActivity

以下是 AppActivity.java 不同版本的引擎所在的目录:

cpp
  - proj.android/src/org/cocos2dx/cpp/AppActivity.java
  - proj.android-studio/app/src/org/cocos2dx/cpp/AppActivity.java
  - proj.android/app/src/org/cocos2dx/cpp/AppActivity.java ( from cocos2d-x 3.17)

lua
  - frameworks/runtime-src/proj.android/src/org/cocos2dx/lua/AppActivity.java
  - frameworks/runtime-src/proj.android-studio/app/src/org/cocos2dx/lua/AppActivity.java
  - frameworks/runtime-src/proj.android/app/src/org/cocos2dx/lua/AppActivity.java (from cocos2d-x 3.17)

js
  - frameworks/runtime-src/proj.android/src/org/cocos2dx/javascript/AppActivity.java
  - frameworks/runtime-src/proj.android/app/src/org/cocos2dx/javascript/AppActivity.java ( from cocos2d-x 3.17)

插件版本 < 2.4.0.3

Note: 当你使用 cocos2d-x 源代码时,不同的版本中 Cocos2dxActivity.java 文件的位置也不同。一个确定该文件位置的方法是查看 proj.android/project.properties 。比如:

android.library.reference.1=../../cocos2d-x/cocos/platform/android/java

在这个例子中, Cocos2dxActivity.java 文件应该在如下位置:

../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
onLoadNativeLibraries();
SDKBox.init(this);
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          if(!SDKBox.onActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
          }
    }
    @Override
    protected void onStart() {
          super.onStart();
          SDKBox.onStart();
    }
    @Override
    protected void onStop() {
          super.onStop();
          SDKBox.onStop();
    }
    @Override
    protected void onResume() {
          super.onResume();
          SDKBox.onResume();
    }
    @Override
    protected void onPause() {
          super.onPause();
          SDKBox.onPause();
    }
    @Override
    public void onBackPressed() {
          if(!SDKBox.onBackPressed()) {
            super.onBackPressed();
          }
    }

混淆 (release, 可选)

proguard.config=proguard.cfg
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# cocos2d-x
-keep public class org.cocos2dx.** { *; }
-dontwarn org.cocos2dx.**
-keep public class com.chukong.** { *; }
-dontwarn com.chukong.**

# google play service
-keep public class com.google.android.gms.** { public *; }
-dontwarn com.google.android.gms.**

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

#sdkbox
-keep public class com.sdkbox.** { *; }
-dontwarn com.sdkbox.**

#appnext
-keep class com.appnext.** { *; }
-dontwarn com.appnext.**

注意: 混淆只在 Release 编译模式下有效 (i.e cocos run -m release) debug 编译下不会调用到混淆规则。