AdMob 集成指南
For the C++ version of cocos2d-x v3.x - (all other versions)
集成
首先,您需要在 AdMob 官网注册一个帐号。
然后,用如下命令来集成 SDKBOX AdMob 插件,请确保您可以正常执行的 SDKBOX 安装器.
$ sdkbox import admob
最后,请您仔细阅读官方的 iOS FAQ 以及 Android FAQ 。
重点注意事项
如果您升级到了 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 不能帮你恢复.
JSON 配置
SDKBOX Installer 将会自动在您的 sdkbox_config.json
中插入一份配置样例。请修改这份配置样例,使其能用于您自己的 app 。
智能横幅(smart banner)
设置 width 和 height 的值为 0
"width":0,
"height":0
自适应横幅(adaptive banner)
"width":-1,
"height":-1
自动缓存
不需要配置,该插件会自动缓存广告类型中的广告。当 插屏广告/视频广告 关闭时,也会自动缓存它。
失败时,需要开发者调用 cache
接口去缓存。
type:
- "banner"
- "interstitial"
- "rewarded_video"
- "rewarded_interstitial"
- "appopen"
alignment:
- "top"
- "bottom"
- "left"
- "right"
- "center"
- "top_left" or "left_top"
- "top_right" or "right_top"
- "bottom_left" or "left_bottom"
- "bottom_right" or "right_bottom"
width x height:
- 320x50
- 468x60
- 320x100
- 728x90
- 300x250
- 160x600
- 0x0 # 0x0 means auto size.
Test ID (Google)
type | id |
---|---|
Banner | ca-app-pub-3940256099942544/6300978111 |
Interstitial | ca-app-pub-3940256099942544/1033173712 |
Interstitial Video | ca-app-pub-3940256099942544/8691691433 |
Rewarded Video | ca-app-pub-3940256099942544/5224354917 |
AppOpen | ca-app-pub-3940256099942544/1033173712 |
type | id |
---|---|
Banner | ca-app-pub-3940256099942544/2934735716 |
Interstitial | ca-app-pub-3940256099942544/4411468910 |
Interstitial Video | ca-app-pub-3940256099942544/5135589807 |
Rewarded Video | ca-app-pub-3940256099942544/1712485313 |
AppOpen | ca-app-pub-3940256099942544/5662855259 |
Example:
{
"ios": {
"AdMob":{
"ads":{
"home":{
"id":"ca-app-pub-3940256099942544/2934735716",
"type":"banner",
"alignment":"bottom",
"width":300,
"height":50
},
"gameover":{
"id":"ca-app-pub-3940256099942544/4411468910",
"type":"interstitial"
},
"appopen":{
"type": "appopen",
"id": "ca-app-pub-3940256099942544/5662855259"
}
}
}
},
"android": {
"AdMob":{
"ads":{
"home":{
"id":"ca-app-pub-3940256099942544/6300978111",
"type":"banner",
"alignment":"bottom",
"width":300,
"height":100
},
"gameover":{
"id":"ca-app-pub-3940256099942544/1033173712",
"type":"interstitial"
},
"appopen":{
"id":"ca-app-pub-3940256099942544/1033173712",
"type":"appopen"
}
}
}
}
}
Usage
初始化 AdMob
在您的代码的合适的位置初始化这个插件,我们建议您在 AppDelegate:applicationDidFinishLaunching()
或者 AppController:didFinishLaunchingWithOptions()
中进行初始化。并确保您的代码中包含了正确的头文件。举例如下:
#include "PluginAdMob/PluginAdMob.h"
AppDelegate::applicationDidFinishLaunching()
{
sdkbox::PluginAdMob::init();
}
缓存广告数据
sdkbox::PluginAdMob::cache("home");
sdkbox::PluginAdMob::cache("gameover");
注意:AdMob 需要在使用前缓存广告数据,并且该插件不支持自动缓存。缓存广告数据可能会花费数分钟的时间,一旦缓存完成您将可以看到广告内容。在缓存期间,广告数据是不可用的状态。
显示广告
sdkbox::PluginAdMob::show("home");
sdkbox::PluginAdMob::show("gameover");
隐藏广告
您不能隐藏插播式广告。
sdkbox::PluginAdMob::hide("home");
检查广告数据可用性
sdkbox::PluginAdMob::isAvailable("home");
sdkbox::PluginAdMob::isAvailable("gameover");
实现 AdMobListener
- 您可以实现 AdMobListener 用来设置回调,比如当一个视频播放完成的时候。
#include "PluginAdMob/PluginAdMob.h"
class MyClass : public sdkbox::AdMobListener
{
private:
void adViewDidReceiveAd(const std::string &name) {}
void adViewDidFailToReceiveAdWithError(const std::string &name, const std::string &msg) {}
void adViewWillPresentScreen(const std::string &name) {}
void adViewDidDismissScreen(const std::string &name) {}
void adViewWillDismissScreen(const std::string &name) {}
void adViewWillLeaveApplication(const std::string &name) {}
void reward(const std::string &name, const std::string ¤cy, double amount) {}
}
API Reference
Methods
static bool init ( ) ;
initialize the plugin instance.
static void setListener ( AdMobListener * listener ) ;
Set listener to listen for admob events
static AdMobListener * getListener ( ) ;
Get the listener
static void removeListener ( ) ;
Remove the listener, and can't listen to events anymore
static std::string getVersion ( ) ;
Use this to get the version of the SDK. @return The version of the SDK.
static void setTestDevices ( const std::string & devices ) ;
Set test devices
static void cache ( const std::string & name ) ;
Cache ad with @name
static void show ( const std::string & name ) ;
show ad with @name
static void hide ( const std::string & name ) ;
hide ad with @name
static bool isAvailable ( const std::string & name ) ;
check whether ad available with @name
static int getCurrBannerWidth ( ) ;
get width of current banner
static int getCurrBannerHeight ( ) ;
get height of current banner
Listeners
void adViewDidReceiveAd ( const std::string & name ) {
void adViewDidFailToReceiveAdWithError ( const std::string & name ,
const std::string & msg ) {
void adViewWillPresentScreen ( const std::string & name ) {
void adViewDidDismissScreen ( const std::string & name ) {
void adViewWillDismissScreen ( const std::string & name ) {
void adViewWillLeaveApplication ( const std::string & name ) {
手动集成
如果 SDKBOX 安装器 安装插件失败了,那么需要手动集成插件.如果安装器安装插件成功了,那么不需要,也没必要,按文档再手动集成一次.
下面列出的的步骤一般很少用到.如果你按下面的步骤完成了集成,请在完成集成后,再按步骤检查一次.
iOS 平台手动集成
拖拽下列 framework 从 AdMob
插件包的 plugins/ios 目录到您的 Xcode 工程中,在添加 frameworks 的时候,请勾选 Copy items if needed
。
sdkbox.framework
PluginAdMob.framework
GoogleMobileAds.framework
You also need to add the following system frameworks, if you don't already have them:
AdSupport.framework
AudioToolbox.framework
AVFoundation.framework
CoreGraphics.framework
CoreMedia.framework
CoreTelephony.framework
EventKit.framework
EventKitUI.framework
MessageUI.framework
StoreKit.framework
SystemConfiguration.framework
GameController.framework
MediaPlayer.framework
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
目录拷贝所有文件到您的工程的 proj.android/libs 目录。
-
如果你使用 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.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
编辑 Android.mk
编辑 proj.android/jni/Android.mk
:
为 LOCAL_WHOLE_STATIC_LIBRARIES 添加额外的库:
LOCAL_WHOLE_STATIC_LIBRARIES += PluginAdMob
LOCAL_WHOLE_STATIC_LIBRARIES += sdkbox
在所有 import-module 语句之前添加一条 call 语句:
$(call import-add-path,$(LOCAL_PATH))
在最后添加额外的 import-module 语句:
$(call import-module, ./sdkbox)
$(call import-module, ./pluginadmob)
这意味着您的语句顺序看起来像是这样:
$(call import-add-path,$(LOCAL_PATH))
$(call import-module, ./sdkbox)
$(call import-module, ./pluginadmob)
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
- 找到 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();
}
}
使用 Proguard (release模式下可选)
- 编辑
project.properties
文件, 指定一个Proguard
配置文件。比如:
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.**
Note: Proguard 只能工作在 Release 模式下 (比如: cocos run -m release
) debug 模式下不会触发 Proguard 。