Appodeal 集成指南
For the Javascript version of cocos2d-x v3.x - (all other versions)
集成
在您确保正确安装了 SDKBOX installer 的情况下,运行下面的命令来集成 SDKBOX Appodeal 插件。
$ sdkbox import appodeal
重点注意事项
如果您升级到了 Xcode7, 则需要以下额外步骤来确保插件工作正常:
禁用应用程序安全传输策略
添加以下项到 plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
添加后的文件内容看起来就像这样:
禁止 Bitcode 支持
您必须禁止 Bitcode 的支持,否则将会编译失败。
游戏全屏配置
如果您的游戏不同时支持横竖屏,则必须在 Xcode 中选中 Requires full screen
,否则将不会通过 Apple 的审核。
canOpenURL 白名单
取决于您使用哪些插件。需要在 info.plist
的 LSApplicationQueriesSchemes
下添加名单。
关于 Creator 工程
Creator 导出工程会修改工程的配置, 这可能会影响 SDKBox 对工程的配置修改. 所以可以有以下做法(任选其一):
- 保存导出工程中的修改, 对于 SDKBox 来说可能有这些文件(mk, gradle, gradle.properties, AppDelegate.cpp, ...), 导出后再恢复对应该文件
- 在每一次 Creator 导出工程后, 重新 import 插件.
推荐第一种, 但是第一种的麻烦点在于, 对于第一次(或很久没接触的人)可能会有露掉某个文件 第二种, 很方便, 它的麻烦点在于, 如果你对工程有自己的修改, SDKBox 的重新 import 不能帮你恢复.
如果你用到相关的函数,请添加如下项到你的工程中的 Info.plist 中
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Advertising</string>
<key>NSCalendarsUsageDescription</key>
<string>Advertising</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Advertising</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Advertising</string>
JSON 配置
SDKBOX Installer 将会自动在您的 sdkbox_config.json
中插入一份配置样例。请修改这份配置样例,使其能用于您自己的 app 。
对于一个 Appodeal 插件的配置样例,您需要将其中的 <app_key>
替换成您特定的 Appodeal 帐号中的信息。
"Appodeal":{
"app_key":"2cfc9cc638980eb7f5ff35d6eb63dbe404503151ccc451ed"
}
使用
注册 Javascript 函数
- 修改
./frameworks/runtime-src/Classes/AppDelegate.cpp
包含如下头文件:
#include "PluginAppodealJS.hpp"
#include "PluginAppodealJSHelper.h"
- 修改
./frameworks/runtime-src/Classes/AppDelegate.cpp
确保有如下调用:
sc->addRegisterCallback(register_all_PluginAppodealJS);
sc->addRegisterCallback(register_all_PluginAppodealJS_helper);
初始化 Appodeal
- 在您的代码中合适的地方调用
init()
, 我们建议在app.js
初始化, 比如:
sdkbox.PluginAppodeal.init();
使用 Appodeal
plugin.setUserVkId("user id");
plugin.cacheAd(15);
接收 Appodeal events (可选)
var plugin = sdkbox.PluginAppodeal
plugin.setListener({
onBannerDidLoadAd: function() { cc.log("onBannerDidLoadAd") },
onBannerDidFailToLoadAd: function() { cc.log("onBannerDidFailToLoadAd") },
onBannerDidClick: function() { cc.log("onBannerDidClick") },
onBannerPresent: function() { cc.log("onBannerPresent") },
onInterstitialDidLoadAd: function() { cc.log("onInterstitialDidLoadAd") },
onInterstitialDidFailToLoadAd: function() { cc.log("onInterstitialDidFailToLoadAd") },
onInterstitialWillPresent: function() { cc.log("onInterstitialWillPresent") },
onInterstitialDidDismiss: function() { cc.log("onInterstitialDidDismiss") },
onInterstitialDidClick: function() { cc.log("onInterstitialDidClick") },
onVideoDidLoadAd: function() { cc.log("onVideoDidLoadAd") },
onVideoDidFailToLoadAd: function() { cc.log("onVideoDidFailToLoadAd") },
onVideoDidPresent: function() { cc.log("onVideoDidPresent") },
onVideoWillDismiss: function() { cc.log("onVideoWillDismiss") },
onVideoDidFinish: function() { cc.log("onVideoDidFinish") }
})
plugin.init()
API Reference
Methods
sdkbox.PluginAppodeal.init();
initialize the plugin instance.
sdkbox.PluginAppodeal.setListener(listener);
Set listener to listen for Appodeal events
sdkbox.PluginAppodeal.setDebugEnabled(debugEnabled);
sdkbox.PluginAppodeal.showAd(style);
sdkbox.PluginAppodeal.cacheAd(type);
sdkbox.PluginAppodeal.hideBanner();
sdkbox.PluginAppodeal.isReadyForShowWithStyle(showStyle);
sdkbox.PluginAppodeal.setUserVkId(vkId);
sdkbox.PluginAppodeal.setUserFacebookId(facebookId);
sdkbox.PluginAppodeal.setUserEmail(email);
sdkbox.PluginAppodeal.setUserBirthday(birthday);
sdkbox.PluginAppodeal.setUserAge(age);
sdkbox.PluginAppodeal.setUserGender(gender);
sdkbox.PluginAppodeal.setUserOccupation(occupation);
sdkbox.PluginAppodeal.setUserRelationship(relationship);
sdkbox.PluginAppodeal.setUserSmokingAttitude(smokingAttitude);
sdkbox.PluginAppodeal.setUserAlcoholAttitude(alcoholAttitude);
sdkbox.PluginAppodeal.setUserInterests(interests);
Listeners
onBannerDidLoadAd();
trigger when banner ad load
onBannerDidFailToLoadAd();
trigger when banner ad fail to load
onBannerDidClick();
trigger when banner ad clicked
onBannerPresent();
trigger when banner ad present
onInterstitialDidLoadAd();
trigger when interstitial ad load
onInterstitialDidFailToLoadAd();
trigger when interstitial ad fail to load
onInterstitialWillPresent();
trigger when interstitial ad present
onInterstitialDidDismiss();
trigger when interstitial dismiss
onInterstitialDidClick();
trigger when interstitial ad clicked
onVideoDidLoadAd();
trigger when video load
onVideoDidFailToLoadAd();
trigger when video fail to load
onVideoDidPresent();
trigger when video present
onVideoWillDismiss();
trigger when video dismiss
onVideoDidFinish();
trigger when video finish
手动集成
如果 SDKBOX 安装器 安装插件失败了,那么需要手动集成插件.如果安装器安装插件成功了,那么不需要,也没必要,按文档再手动集成一次.
下面列出的的步骤一般很少用到.如果你按下面的步骤完成了集成,请在完成集成后,再按步骤检查一次.
iOS 平台手动集成
拖拽下列 framework 从 AdColony
插件包的 plugins/ios 目录到您的 Xcode 工程中,在添加 frameworks 的时候,请勾选 Copy items if needed
。
sdkbox.framework
PluginAppodeal.framework
Appodeal.framework
plugin_appodeal_res_bundle
上面的 frameworks 依赖于大量其他 frameworks。如果您没有添加它们,您也需要添加下列这些系统 frameworks:
AdSupport.framework
AudioToolbox.framework
AVFoundation.framework
CFNetwork.framework
CoreFoundation.framework
CoreGraphics.framework
CoreImage.framework
CoreLocation.framework
CoreMedia.framework
CoreMotion.framework
CoreTelephony.framework
EventKit.framework
EventKitUI.framework
libc++.tbd
libsqlite3.tbd
libxml2.2.tbd
libz.tbd
MediaPlayer.framework
MessageUI.framework
MobileCoreServices.framework
QuartzCore.framework
Security.framework
Social.framework
StoreKit.framework
SystemConfiguration.framework
Twitter.framework
UIKit.framework
WebKit.framework
GameController.framework
把 plugin/jsbindings
文件夹中所有的头文件和源文件都拷贝到你的工程的 Classes
文件夹中.
把刚刚拷贝的文件拖动到 Xcode 中或使用 File -> Add files to... 来添加.
Android 手动集成
SDKBox 支持三种 Android 工程, command-line, eclipse 和 Android Studio.
- command-line 和 eclipse 类型的项目,
<project_root>
指代proj.android
. - Android Studio 类型的项目,
<project_root>
指代proj.android-studio
.
拷贝文件
从插件安装包中的 plugin/android/libs
目录拷贝下列 jar 文件到您的工程的 proj.android/libs 目录。
PluginAppodeal.jar
sdkbox.jar
android-support-v4-22.2.1.jar
applovin-sdk-6.0.1.jar
appodeal-1.13.1.jar
chartboost-5.2.0.jar
my-target-4.0.13.jar
unity-ads-1.4.7.jar
-
如果你使用 cocos2d-x 源码,拷贝 jar 文件到:
Android command-line:
cocos2d/cocos/platform/android/java/libs
Android Studio:
cocos2d/cocos/platform/android/libcocos2dx/libs
-
如果你使用 cocos2d-js 或者 lua ,拷贝 jar 文件到:
Android command-line:
frameworks/cocos2d-x/cocos/platform/android/java/libs
Android Studio:
frameworks/cocos2d-x/cocos/platform/android/libcocos2dx/libs
-
如果你使用 cocos2d-x 预编译包,拷贝 jar 文件到:
Android command-line:
proj.android/libs
拷贝 jni 库
从 plugin/android/jni/
拷贝并覆盖 <your_project_root>/jni/
目录.
编辑 AndroidManifest.xml
在标签 application tag 上添加下列权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
在接近文件底部的位置,拷贝并且粘贴下列定义到 application tags 标签结尾处。
<meta-data android:name="com.appodeal.framework" android:value="android" />
<activity android:name="com.appodeal.ads.InterstitialActivity"
android:configChanges="orientation|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity android:name="com.appodeal.ads.VideoActivity"
android:configChanges="orientation|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity android:name="com.appodeal.ads.LoaderActivity"
android:configChanges="orientation|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.Translucent" />
<activity android:name="com.chartboost.sdk.CBImpressionActivity"
android:theme="@android:style/Theme.Translucent"
android:excludeFromRecents="true" />
<activity android:name="com.applovin.adview.AppLovinInterstitialActivity"
android:theme="@android:style/Theme.Translucent" />
<activity android:name="com.mopub.mobileads.MoPubActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.Translucent" />
<activity android:name="com.mopub.common.MoPubBrowser"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity android:name="com.mopub.mobileads.MraidActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity android:name="com.mopub.mobileads.MraidVideoPlayerActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity android:name="org.nexage.sourcekit.mraid.MRAIDBrowser"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
android:theme="@android:style/Theme.Translucent" />
<activity android:name="com.amazon.device.ads.AdActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity android:name="com.unity3d.ads.android.view.UnityAdsFullscreenActivity"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true" />
<activity android:name="ru.mail.android.mytarget.ads.MyTargetActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
<activity android:name="org.nexage.sourcekit.vast.activity.VASTActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
<activity android:name="com.facebook.ads.InterstitialAdActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity android:name="com.jirbo.adcolony.AdColonyOverlay"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name="com.jirbo.adcolony.AdColonyFullscreen"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" />
<activity android:name="com.jirbo.adcolony.AdColonyBrowser"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" />
<activity android:name="com.vungle.publisher.FullScreenAdActivity"
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 += PluginAppodeal
LOCAL_WHOLE_STATIC_LIBRARIES += sdkbox
在所有 import-module 语句之前添加一条 call 语句:
$(call import-add-path,$(LOCAL_PATH))
在最后添加额外的 import-module 语句:
$(call import-module, ./sdkbox)
$(call import-module, ./pluginappodeal)
这意味着您的语句顺序看起来像是这样:
$(call import-add-path,$(LOCAL_PATH))
$(call import-module, ./sdkbox)
$(call import-module, ./pluginappodeal)
注意: 如果您使用的是 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
把 plugin/jsbindings
文件夹中所有的头文件和源文件都拷贝到你的工程的 Classes
文件夹中.
把你刚刚拷贝的 .cpp
文件添加到 Android.mk
文件的的 LOCAL_SRC_FILES 项.比如
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp \
../../Classes/NewSourceFile.cpp
修改 AppActivity.java
插件版本 >= 2.4.0.3
- 找到 AppActivity.java 文件
find . -name "AppActivity.java"
- 把
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
-
如果您使用 cocos2d-x 源代码,假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/ lib/Cocos2dxActivity.java
-
如果您使用 cocos2dx-x 预编译库, 假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:./src/org/cocos2dx/lib/Cocos2dxActivity.java
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
- 修改
Cocos2dxActivity.java
文件,导入如下包:
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
- 然后,修改
Cocos2dxActivity
类的onCreate(final Bundle savedInstanceState)
函数,添加一个调用语句SDKBox.init(this);
。添加的位置非常重要,必须在调用onLoadNativeLibraries();
之后。如下:
onLoadNativeLibraries();
SDKBox.init(this);
-
最后, 我需要提供合适的 overrides 方法的代码。这里有一些约定如下。
-
如果这个被列出的方法没有在
SDKBox
中定义,那么__定义它__。 -
如果这个被列出的方法已经被定义在
SDKBox
中,那么请调用这个在SDKBox
中的__同名方法__。
-
@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, 可选)
- 编辑
project.properties
,写入一个Proguard
配置. Example:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
- 编辑这个文件,包含如下内容:
# appodeal
-keep class com.appodeal.** { *; }
-keep class com.amazon.** { *; }
-keep class com.mopub.** { *; }
-keep class org.nexage.** { *; }
-keep class com.applovin.** { *; }
-keep class com.chartboost.** { *; }
-keep class com.unity3d.ads.** { *; }
-keep class com.applifier.** { *; }
-keep class com.yandex.** { *; }
-keep class com.inmobi.** { *; }
-keep class ru.mail.android.mytarget.** { *; }
-keep class com.google.android.gms.ads.** { *; }
-keep class com.google.android.gms.common.GooglePlayServicesUtil { *; }
-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;
}
-dontwarn com.facebook.ads.**
-dontwarn com.jirbo.adcolony.**
-dontwarn com.vungle.**
-dontwarn com.startapp.**
-dontwarn com.yandex.**
-dontwarn com.inmobi.**
-keep class android.support.v4.app.Fragment { *; }
-keep class android.support.v4.app.FragmentActivity { *; }
-keep class android.support.v4.app.FragmentManager { *; }
-keep class android.support.v4.app.FragmentTransaction { *; }
-keep class android.support.v4.content.LocalBroadcastManager { *; }
-keep class android.support.v4.util.LruCache { *; }
-keep class android.support.v4.view.PagerAdapter { *; }
-keep class android.support.v4.view.ViewPager { *; }
-dontwarn com.appodeal.**
-dontwarn ru.mail.android.mytarget.**
# 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 class com.sdkbox.** { *; }
-dontwarn com.sdkbox.**
注意: 混淆只在 Release 模式下有效 (比如 cocos run -m release
), 在 debug 模式下,不会调到混淆规则.