Merge pull request #2419 from natural-law/master

Add protocol Ads & plugin Admob
This commit is contained in:
minggo 2013-04-22 01:51:35 -07:00
commit 25a0927bf7
41 changed files with 1887 additions and 41 deletions

View File

@ -0,0 +1,68 @@
#ifndef __CCX_ADS_ADMOB_H__
#define __CCX_ADS_ADMOB_H__
#include "ProtocolAds.h"
#include <map>
#include <string>
namespace cocos2d { namespace plugin {
class AdsAdmob : public ProtocolAds
{
PLUGIN_REGISTER_DECL(AdsAdmob)
public:
typedef enum {
eSizeBanner = 0,
eSizeIABMRect,
eSizeIABBanner,
eSizeIABLeaderboard,
} ESizeAdmobBanner;
/**
@brief plugin initialization
*/
virtual bool init();
/**
@brief initialize the application info
@param appInfo This parameter is the info of application, must contains:
AdmobID The publisher ID of admob.
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
virtual void initAppInfo(TAppInfo appInfo);
/**
@brief show banner ads at specified position
@param pos The position where the banner view be shown
@param sizeEnum The size of the banner view. Use the value in ESizeAdmobBanner
*/
virtual void showBannerAd(EBannerPos pos, int sizeEnum);
/**
@brief hide the banner ads view
*/
virtual void hideBannerAd();
/**
@brief Set whether needs to output logs to console.
@param debug if true debug mode enabled, or debug mode disabled.
*/
virtual void setDebugMode(bool debug);
/**
@brief Add the test device ID
@param deviceID The device ID
*/
void addTestDevice(const char* deviceID);
virtual const char* getPluginVersion() { return "v0.1.01"; };
virtual const char* getSDKVersion();
virtual ~AdsAdmob();
};
}} // namespace cocos2d { namespace plugin {
#endif /* __CCX_ADS_ADMOB_H__ */

View File

@ -0,0 +1,60 @@
[admob]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = pluginx_admob
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = plugin
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include/linux -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/include -I%(androidndkdir)s/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/lib/gcc/arm-linux-androideabi/4.6/include
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/3.1/include
clang_flags = -nostdinc -x c++
cocos_headers = -I%(pluginxdir)s/protocols/include -I%(pluginxdir)s/plugins/admob/include
cocos_flags = -DANDROID
cxxgenerator_headers = -I%(cxxgeneratordir)s/targets/spidermonkey/common
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s
# what headers to parse
headers = %(pluginxdir)s/plugins/admob/include/IAPAlipay.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^CCMenu*$".
classes = IAPAlipay
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip = *::[createPlugin]
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# classes for which there will be no "parent" lookup
classes_have_no_parents =
# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =
# classes that create no constructor
# CCSet is special and we will use a hand-written constructor
abstract_classes = IAPAlipay
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = yes

View File

@ -0,0 +1,58 @@
#include "AdsAdmob.h"
#include "PluginUtils.h"
namespace cocos2d { namespace plugin {
PLUGIN_REGISTER_IMPL(AdsAdmob)
AdsAdmob::~AdsAdmob()
{
}
bool AdsAdmob::init()
{
return PluginUtils::initJavaPlugin(this, "org.cocos2dx.plugin.AdsAdmob");
}
void AdsAdmob::initAppInfo(TAppInfo appInfo)
{
ProtocolAds::initAppInfo(appInfo);
}
void AdsAdmob::showBannerAd(EBannerPos pos, int sizeEnum)
{
ProtocolAds::showBannerAd(pos, sizeEnum);
}
void AdsAdmob::hideBannerAd()
{
ProtocolAds::hideBannerAd();
}
const char* AdsAdmob::getSDKVersion()
{
return ProtocolAds::getSDKVersion();
}
void AdsAdmob::setDebugMode(bool debug)
{
ProtocolAds::setDebugMode(debug);
}
void AdsAdmob::addTestDevice(const char* deviceID)
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "addTestDevice"
, "(Ljava/lang/String;)V"))
{
jstring strDeviceID = t.env->NewStringUTF(deviceID);
t.env->CallVoidMethod(pData->jobj, t.methodID, strDeviceID);
t.env->DeleteLocalRef(strDeviceID);
t.env->DeleteLocalRef(t.classID);
}
}
}} // namespace cocos2d { namespace plugin {

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="lib" path="sdk/GoogleAdMobAdsSdk.jar"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>libPluginAdmob</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>android</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/platform/android</locationURI>
</link>
<link>
<name>include</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/include</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -0,0 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.cocos2dx.libAdsAdmob"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />
</manifest>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifestConfig xmlns:android="http://schemas.android.com/apk/res/android">
<applicationCfg keyword="com.google.ads.AdActivity">
<activity android:name="com.google.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
</applicationCfg>
<permissionCfg>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</permissionCfg>
</manifestConfig>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="libPluginAdmob" default="plugin-publish">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${plugin.dir}/tools/android/build_common.xml" />
</project>

View File

@ -0,0 +1,20 @@
# set params
PLUGIN_ANDROID_ROOT=$(cd "$(dirname "$0")"; pwd)
if [ ! "${PLUGIN_ROOT}" ]; then
PLUGIN_ROOT="$PLUGIN_ANDROID_ROOT"/../..
fi
# build
"$ANDROID_NDK_ROOT"/ndk-build -C "$PLUGIN_ANDROID_ROOT" \
NDK_MODULE_PATH="$PLUGIN_ROOT"
echo
if [ "0" != "$?" ]; then
echo "Build error occoured!!!"
exit 1
fi
echo
echo "Native build action success."
exit 0

View File

@ -0,0 +1,29 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := PluginAdmobStatic
LOCAL_MODULE_FILENAME := libPluginAdmobStatic
LOCAL_SRC_FILES := \
$(addprefix ../../platform/android/, \
AdsAdmob.cpp \
) \
LOCAL_CFLAGS :=
LOCAL_EXPORT_CFLAGS :=
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_WHOLE_STATIC_LIBRARIES := PluginProtocolStatic
LOCAL_LDLIBS := -landroid
LOCAL_LDLIBS += -llog
include $(BUILD_STATIC_LIBRARY)
$(call import-module, protocols/proj.android/jni)

View File

@ -0,0 +1,7 @@
# it is needed for ndk-r5
APP_STL := gnustl_static
APP_CPPFLAGS += -frtti
APP_MODULES := PluginAdmobStatic
APP_ABI :=armeabi
#APP_ABI :=x86
#APP_ABI :=mips mips-r2 mips-r2-sf armeabi

View File

@ -0,0 +1,16 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-7
android.library=true
android.library.reference.1=../../../protocols/proj.android

View File

View File

@ -0,0 +1 @@
3cf479a2b1f3e12b9d61e98d742baeb247401093

View File

@ -0,0 +1,201 @@
package org.cocos2dx.plugin;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import org.cocos2dx.plugin.InterfaceAds.AdsAdapter;
import com.google.ads.*;
import com.google.ads.AdRequest.ErrorCode;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.WindowManager;
public class AdsAdmob implements AdsAdapter {
private static final String LOG_TAG = "AdsAdmob";
private static Activity mContext = null;
private static boolean bDebug = false;
// private static Handler mHandler = null;
// private static AdsAdmob mAdapter = null;
private AdView adView = null;
private String mPublishID = "";
private Set<String> mTestDevices = null;
private WindowManager mWm = null;
private static final int SIZE_BANNER = 0;
private static final int SIZE_IABMRect = 1;
private static final int SIZE_IABBanner = 2;
private static final int SIZE_IABLeaderboard = 3;
protected static void LogE(String msg, Exception e) {
Log.e(LOG_TAG, msg, e);
e.printStackTrace();
}
protected static void LogD(String msg) {
if (bDebug) {
Log.d(LOG_TAG, msg);
}
}
public AdsAdmob(Context context) {
mContext = (Activity) context;
//mAdapter = this;
}
@Override
public void setDebugMode(boolean debug) {
bDebug = debug;
}
@Override
public String getSDKVersion() {
return "6.3.1";
}
@Override
public void initAppInfo(Hashtable<String, String> appInfo) {
try {
mPublishID = appInfo.get("AdmobID");
LogD("init AppInfo : " + mPublishID);
} catch (Exception e) {
LogE("initAppInfo, The format of appInfo is wrong", e);
}
}
@Override
public void showBannerAd(int pos, int sizeEnum) {
final int curPos = pos;
final int curSize = sizeEnum;
PluginWrapper.runOnMainThread(new Runnable() {
@Override
public void run() {
// destory the ad view before
if (null != adView) {
if (null != mWm) {
mWm.removeView(adView);
}
adView.destroy();
adView = null;
}
AdSize size = AdSize.BANNER;
switch (curSize) {
case AdsAdmob.SIZE_BANNER:
break;
case AdsAdmob.SIZE_IABMRect:
break;
case AdsAdmob.SIZE_IABBanner:
break;
case AdsAdmob.SIZE_IABLeaderboard:
break;
default:
break;
}
adView = new AdView(mContext, size, mPublishID);
AdRequest req = new AdRequest();
try {
if (mTestDevices != null) {
Iterator<String> ir = mTestDevices.iterator();
while(ir.hasNext())
{
req.addTestDevice(ir.next());
}
}
} catch (Exception e) {
LogE("Error during add test device", e);
}
adView.loadAd(req);
adView.setAdListener(new AdmobAdListener());
if (null == mWm) {
mWm = (WindowManager) mContext.getSystemService("window");
}
InterfaceAds.addAdView(mWm, adView, curPos);
}
});
}
@Override
public void hideBannerAd() {
PluginWrapper.runOnMainThread(new Runnable() {
@Override
public void run() {
if (null != adView) {
if (null != mWm) {
mWm.removeView(adView);
}
adView.destroy();
adView = null;
}
}
});
}
public void addTestDevice(String deviceID) {
LogD("addTestDevice invoked : " + deviceID);
if (null == mTestDevices) {
mTestDevices = new HashSet<String>();
}
mTestDevices.add(deviceID);
}
private class AdmobAdListener implements AdListener {
@Override
public void onDismissScreen(Ad arg0) {
LogD("onDismissScreen invoked");
InterfaceAds.dismissScreen();
}
@Override
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
int errorNo = InterfaceAds.UNKNOWN_ERROR;
String errorMsg = "Unknow error";
switch (arg1) {
case NETWORK_ERROR:
errorNo = InterfaceAds.NETWORK_ERROR;
errorMsg = "Network error";
break;
case INVALID_REQUEST:
errorNo = InterfaceAds.REQUESTING_ERROR;
errorMsg = "The ad request is invalid";
break;
case NO_FILL:
errorMsg = "The ad request is successful, but no ad was returned due to lack of ad inventory.";
break;
default:
break;
}
LogD("failed to receive ad : " + errorNo + " , " + errorMsg);
InterfaceAds.failedToReceiveAd(errorNo, errorMsg);
}
@Override
public void onLeaveApplication(Ad arg0) {
LogD("onLeaveApplication invoked");
}
@Override
public void onPresentScreen(Ad arg0) {
LogD("onPresentScreen invoked");
InterfaceAds.presentScreen();
}
@Override
public void onReceiveAd(Ad arg0) {
LogD("onReceiveAd invoked");
InterfaceAds.receiveAd();
}
}
}

View File

@ -0,0 +1,103 @@
#ifndef __CCX_PROTOCOL_ADS_H__
#define __CCX_PROTOCOL_ADS_H__
#include "PluginProtocol.h"
#include <map>
#include <string>
namespace cocos2d { namespace plugin {
typedef std::map<std::string, std::string> TAppInfo;
class AdListener
{
public:
typedef enum
{
eUnknownError = 0,
eNetworkError,
} EAdErrorCode;
virtual void onReceiveAd() {}
virtual void onPresentScreen() {}
virtual void onFailedToReceiveAd(EAdErrorCode code, const char* msg) {}
virtual void onDismissScreen() {}
};
class ProtocolAds : public PluginProtocol
{
public:
typedef enum {
ePosTop = 0,
ePosTopLeft,
ePosTopRight,
ePosBottom,
ePosBottomLeft,
ePosBottomRight,
} EBannerPos;
/**
@brief plugin initialization
*/
virtual bool init();
/**
@brief initialize the application info
@param appInfo This parameter is the info of aplication,
different plugin have different format
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
virtual void initAppInfo(TAppInfo appInfo);
/**
@brief show banner ads at specified position
@param pos The position where the banner view be shown
@param sizeEnum The size of the banner view.
In different plugin, it's have different mean.
Pay attention to the subclass definition
*/
virtual void showBannerAd(EBannerPos pos, int sizeEnum);
/**
@brief hide the banner ads view
*/
virtual void hideBannerAd();
/**
@brief Set whether needs to output logs to console.
@param debug If true debug mode enabled, or debug mode disabled.
*/
virtual void setDebugMode(bool debug);
/**
@brief set the Ads listener
*/
static void setAdListener(AdListener* pListener)
{
m_pListener = pListener;
}
// For the callbak methods
static void receiveAd();
static void presentScreen();
static void failedToReceiveAd(AdListener::EAdErrorCode code, const char* msg);
static void dismissScreen();
virtual const char* getPluginVersion() { return "ProtocolAds, v0.1.01 , subclass should override this interface!"; };
virtual const char* getSDKVersion();
virtual const char* getPluginName() = 0;
protected:
ProtocolAds();
public:
virtual ~ProtocolAds();
protected:
static AdListener* m_pListener;
};
}} // namespace cocos2d { namespace plugin {
#endif /* __CCX_PROTOCOL_ADS_H__ */

View File

@ -15,9 +15,9 @@ namespace cocos2d { namespace plugin {
class PluginUtils
{
public:
static jobject createJavaMapObject(PluginJniMethodInfo&t, std::map<std::string, std::string>* paramMap);
static bool initJavaPlugin(PluginProtocol* pPlugin, const char* className);
static JNIEnv* getEnv();
static jobject createJavaMapObject(PluginJniMethodInfo&t, std::map<std::string, std::string>* paramMap);
static bool initJavaPlugin(PluginProtocol* pPlugin, const char* className);
static JNIEnv* getEnv();
static PluginJavaData* getPluginJavaData(PluginProtocol* pKeyObj);
static void setPluginJavaData(PluginProtocol* pKeyObj, PluginJavaData* pData);
@ -26,18 +26,33 @@ public:
template <typename T>
static void callJavaFunctionWithName_oneBaseType(PluginProtocol* thiz, const char* funcName, const char* paramCode, T param)
{
return_if_fails(funcName != NULL && strlen(funcName) > 0);
return_if_fails(paramCode != NULL && strlen(paramCode) > 0);
return_if_fails(funcName != NULL && strlen(funcName) > 0);
return_if_fails(paramCode != NULL && strlen(paramCode) > 0);
PluginJavaData* pData = PluginUtils::getPluginJavaData(thiz);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, funcName
, paramCode))
{
t.env->CallVoidMethod(pData->jobj, t.methodID, param);
t.env->DeleteLocalRef(t.classID);
}
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, funcName
, paramCode))
{
t.env->CallVoidMethod(pData->jobj, t.methodID, param);
t.env->DeleteLocalRef(t.classID);
}
}
static void callJavaFunctionWithName(PluginProtocol* thiz, const char* funcName)
{
return_if_fails(funcName != NULL && strlen(funcName) > 0);
PluginJavaData* pData = PluginUtils::getPluginJavaData(thiz);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, funcName
, "()V"))
{
t.env->CallVoidMethod(pData->jobj, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
}
};

View File

@ -0,0 +1,157 @@
#include "ProtocolAds.h"
#include "PluginJniHelper.h"
#include <android/log.h>
#include "PluginUtils.h"
#include "PluginJavaData.h"
#if 1
#define LOG_TAG "ProtocolAds"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
#define LOGD(...)
#endif
namespace cocos2d { namespace plugin {
extern "C" {
JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceAds_nativeReceiveAd(JNIEnv* env, jobject thiz) {
ProtocolAds::receiveAd();
}
JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceAds_nativePresentScreen(JNIEnv* env, jobject thiz) {
ProtocolAds::presentScreen();
}
JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceAds_nativeFailedToReceiveAd(JNIEnv* env, jobject thiz, jint ret, jstring msg) {
std::string strMsg = PluginJniHelper::jstring2string(msg);
ProtocolAds::failedToReceiveAd((AdListener::EAdErrorCode) ret, strMsg.c_str());
}
JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceAds_nativeDismissScreen(JNIEnv* env, jobject thiz) {
ProtocolAds::dismissScreen();
}
}
AdListener* ProtocolAds::m_pListener = NULL;
ProtocolAds::ProtocolAds()
{
}
ProtocolAds::~ProtocolAds()
{
PluginUtils::erasePluginJavaData(this);
}
bool ProtocolAds::init()
{
return true;
}
void ProtocolAds::initAppInfo(TAppInfo appInfo)
{
if (appInfo.empty())
{
LOGD("The application info is empty!");
return;
}
else
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "initAppInfo"
, "(Ljava/util/Hashtable;)V"))
{
// generate the hashtable from map
jobject obj_Map = PluginUtils::createJavaMapObject(t, &appInfo);
// invoke java method
t.env->CallVoidMethod(pData->jobj, t.methodID, obj_Map);
t.env->DeleteLocalRef(obj_Map);
t.env->DeleteLocalRef(t.classID);
}
}
}
void ProtocolAds::showBannerAd(EBannerPos pos, int size)
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
LOGD("Class name : %s", pData->jclassName.c_str());
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "showBannerAd"
, "(II)V"))
{
t.env->CallVoidMethod(pData->jobj, t.methodID, pos, size);
t.env->DeleteLocalRef(t.classID);
}
}
void ProtocolAds::hideBannerAd()
{
PluginUtils::callJavaFunctionWithName(this, "hideBannerAd");
}
const char* ProtocolAds::getSDKVersion()
{
std::string verName;
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "getSDKVersion"
, "()Ljava/lang/String;"))
{
jstring ret = (jstring)(t.env->CallObjectMethod(pData->jobj, t.methodID));
verName = PluginJniHelper::jstring2string(ret);
}
return verName.c_str();
}
void ProtocolAds::setDebugMode(bool debug)
{
PluginUtils::callJavaFunctionWithName_oneBaseType(this, "setDebugMode", "(Z)V", debug);
}
void ProtocolAds::receiveAd()
{
LOGD("ProtocolAds::receiveAd invoked!");
if (m_pListener != NULL)
{
m_pListener->onReceiveAd();
}
}
void ProtocolAds::presentScreen()
{
LOGD("ProtocolAds::presentScreen invoked!");
if (m_pListener != NULL)
{
m_pListener->onPresentScreen();
}
}
void ProtocolAds::failedToReceiveAd(AdListener::EAdErrorCode code, const char* msg)
{
LOGD("ProtocolAds::failedToReceiveAd invoked!");
if (m_pListener != NULL)
{
m_pListener->onFailedToReceiveAd(code, msg);
}
}
void ProtocolAds::dismissScreen()
{
LOGD("ProtocolAds::dismissScreen invoked!");
if (m_pListener != NULL)
{
m_pListener->onDismissScreen();
}
}
}} // namespace cocos2d { namespace plugin {

View File

@ -12,6 +12,7 @@ $(addprefix ../../platform/android/, \
PluginUtils.cpp \
ProtocolAnalytics.cpp \
ProtocolIAP.cpp \
ProtocolAds.cpp \
) \
../../PluginManager.cpp \
../../RegisterPlugin.cpp \

View File

@ -0,0 +1,103 @@
package org.cocos2dx.plugin;
import java.util.Hashtable;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
public class InterfaceAds {
public static final int UNKNOWN_ERROR = 0;
public static final int NETWORK_ERROR = 1;
public static final int REQUESTING_ERROR = 2;
public static final int POS_TOP = 0;
public static final int POS_TOP_LEFT = 1;
public static final int POS_TOP_RIGHT = 2;
public static final int POS_BOTTOM = 3;
public static final int POS_BOTTOM_LEFT = 4;
public static final int POS_BOTTOM_RIGHT = 5;
public interface AdsAdapter {
public void initAppInfo(Hashtable<String, String> appInfo);
public void showBannerAd(int pos, int sizeEnum);
public void hideBannerAd();
public void setDebugMode(boolean debug);
public String getSDKVersion();
}
public static void addAdView(WindowManager mWm, View adView, int pos) {
WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams();
mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
switch (pos) {
case POS_TOP:
mLayoutParams.gravity = Gravity.TOP;
break;
case POS_TOP_LEFT:
mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
break;
case POS_TOP_RIGHT:
mLayoutParams.gravity = Gravity.TOP | Gravity.RIGHT;
break;
case POS_BOTTOM:
mLayoutParams.gravity = Gravity.BOTTOM;
break;
case POS_BOTTOM_LEFT:
mLayoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT;
break;
case POS_BOTTOM_RIGHT:
mLayoutParams.gravity = Gravity.BOTTOM | Gravity.RIGHT;
break;
default:
break;
}
mWm.addView(adView, mLayoutParams);
}
public static void receiveAd() {
PluginWrapper.runOnGLThread(new Runnable(){
@Override
public void run() {
InterfaceAds.nativeReceiveAd();
}
});
}
private native static void nativeReceiveAd();
public static void presentScreen() {
PluginWrapper.runOnGLThread(new Runnable(){
@Override
public void run() {
InterfaceAds.nativePresentScreen();
}
});
}
private native static void nativePresentScreen();
public static void failedToReceiveAd(int code, String msg) {
final int eCode = code;
final String eMsg = msg;
PluginWrapper.runOnGLThread(new Runnable(){
@Override
public void run() {
InterfaceAds.nativeFailedToReceiveAd(eCode, eMsg);
}
});
}
private native static void nativeFailedToReceiveAd(int code, String msg);
public static void dismissScreen() {
PluginWrapper.runOnGLThread(new Runnable(){
@Override
public void run() {
InterfaceAds.nativeDismissScreen();
}
});
}
private native static void nativeDismissScreen();
}

View File

@ -1,25 +0,0 @@
package org.cocos2dx.plugin;
import java.util.Hashtable;
public class InterfaceIAPOL {
public interface IAPOLAdapter {
public void initDeveloperInfo(Hashtable<String, String> cpInfo);
public void payForProduct(Hashtable<String, String> cpInfo);
public void setDebugMode(boolean debug);
public String getSDKVersion();
}
public static void payFailedLocally(int ret, String msg) {
final int curRet = ret;
final String curMsg = msg;
PluginWrapper.runOnGLThread(new Runnable() {
@Override
public void run() {
nativePayFailedLocally(curRet, curMsg);
}
});
}
private static native void nativePayFailedLocally(int ret, String msg);
}

View File

@ -0,0 +1,50 @@
#include "AppDelegate.h"
#include "HelloWorldScene.h"
USING_NS_CC;
AppDelegate::AppDelegate() {
}
AppDelegate::~AppDelegate()
{
}
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
CCDirector* pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
pDirector->setOpenGLView(pEGLView);
// turn on display FPS
pDirector->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
// create a scene. it's an autorelease object
CCScene *pScene = HelloWorld::scene();
// run
pDirector->runWithScene(pScene);
return true;
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {
CCDirector::sharedDirector()->stopAnimation();
// if you use SimpleAudioEngine, it must be pause
// SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}
// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
CCDirector::sharedDirector()->startAnimation();
// if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

View File

@ -0,0 +1,38 @@
#ifndef _APP_DELEGATE_H_
#define _APP_DELEGATE_H_
#include "cocos2d.h"
/**
@brief The cocos2d Application.
The reason for implement as private inheritance is to hide some interface call by CCDirector.
*/
class AppDelegate : private cocos2d::CCApplication
{
public:
AppDelegate();
virtual ~AppDelegate();
/**
@brief Implement CCDirector and CCScene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching();
/**
@brief The function be called when the application enter background
@param the pointer of the application
*/
virtual void applicationDidEnterBackground();
/**
@brief The function be called when the application enter foreground
@param the pointer of the application
*/
virtual void applicationWillEnterForeground();
};
#endif // _APP_DELEGATE_H_

View File

@ -0,0 +1,218 @@
#include "HelloWorldScene.h"
#include "PluginManager.h"
USING_NS_CC;
using namespace cocos2d::plugin;
const std::string s_aTestCases[] = {
"Test: Admob",
};
const std::string s_aTestPoses[] = {
"Pos: Top",
"Pos: TopLeft",
"Pos: TopRight",
"Pos: Bottom",
"Pos: BottomLeft",
"Pos: BottomRight",
};
CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
m_pAdmob = dynamic_cast<AdsAdmob*>(PluginManager::getInstance()->loadPlugin("AdsAdmob"));
TAppInfo appInfo;
appInfo["AdmobID"] = "a1516fb6b16b12f";
m_pAdmob->initAppInfo(appInfo);
m_pListener = new MyAdListener();
ProtocolAds::setAdListener(m_pListener);
m_pAdmob->setDebugMode(true);
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
CCPoint posMid = ccp(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2);
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
origin.y + pCloseItem->getContentSize().height/2));
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
CCLabelTTF* label1 = CCLabelTTF::create("ShowAdView", "Arial", 24);
CCMenuItemLabel* pItemShow = CCMenuItemLabel::create(label1, this, menu_selector(HelloWorld::testShow));
pItemShow->setAnchorPoint(ccp(0.5f, 0));
pMenu->addChild(pItemShow, 0);
pItemShow->setPosition(ccpAdd(posMid, ccp(-100, -50)));
CCLabelTTF* label2 = CCLabelTTF::create("HideAdView", "Arial", 24);
CCMenuItemLabel* pItemHide = CCMenuItemLabel::create(label2, this, menu_selector(HelloWorld::testHide));
pItemHide->setAnchorPoint(ccp(0.5f, 0));
pMenu->addChild(pItemHide, 0);
pItemHide->setPosition(ccpAdd(posMid, ccp(100, -50)));
// create optional menu
m_pCaseItem = CCMenuItemToggle::createWithTarget(this,
menu_selector(HelloWorld::caseChanged),
CCMenuItemFont::create( s_aTestCases[0].c_str() ),
NULL );
int caseLen = sizeof(s_aTestCases) / sizeof(std::string);
for (int i = 1; i < caseLen; ++i)
{
m_pCaseItem->getSubItems()->addObject( CCMenuItemFont::create( s_aTestCases[i].c_str() ) );
}
m_pCaseItem->setPosition(ccpAdd(posMid, ccp(-150, 50)));
pMenu->addChild(m_pCaseItem);
m_pPosItem = CCMenuItemToggle::createWithTarget(this,
menu_selector(HelloWorld::posChanged),
CCMenuItemFont::create( s_aTestPoses[0].c_str() ),
NULL );
int posLen = sizeof(s_aTestPoses) / sizeof(std::string);
for (int i = 1; i < posLen; ++i)
{
m_pPosItem->getSubItems()->addObject( CCMenuItemFont::create( s_aTestPoses[i].c_str() ) );
}
m_pPosItem->setPosition(ccpAdd(posMid, ccp(150, 50)));
pMenu->addChild(m_pPosItem);
// init options
m_pAds = m_pAdmob;
m_ePos = ProtocolAds::ePosTop;
this->addChild(pMenu, 1);
return true;
}
void HelloWorld::testShow(CCObject* pSender)
{
if (m_pAds == m_pAdmob)
{
m_pAds->showBannerAd(m_ePos, AdsAdmob::eSizeBanner);
}
}
void HelloWorld::testHide(CCObject* pSender)
{
m_pAds->hideBannerAd();
}
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
CCDirector::sharedDirector()->end();
if (m_pAdmob != NULL)
{
PluginManager::getInstance()->unloadPlugin("AdsAdmob");
m_pAdmob = NULL;
}
if (NULL != m_pListener)
{
delete m_pListener;
m_pListener = NULL;
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
void HelloWorld::caseChanged(CCObject* pSender)
{
std::string strLog = "";
switch (m_pCaseItem->getSelectedIndex())
{
case 0:
m_pAds = m_pAdmob;
strLog = "Admob";
break;
default:
break;
}
CCLog("case selected change to : %s", strLog.c_str());
}
void HelloWorld::posChanged(CCObject* pSender)
{
switch (m_pPosItem->getSelectedIndex())
{
case 0:
m_ePos = ProtocolAds::ePosTop;
break;
case 1:
m_ePos = ProtocolAds::ePosTopLeft;
break;
case 2:
m_ePos = ProtocolAds::ePosTopRight;
break;
case 3:
m_ePos = ProtocolAds::ePosBottom;
break;
case 4:
m_ePos = ProtocolAds::ePosBottomLeft;
break;
case 5:
m_ePos = ProtocolAds::ePosBottomRight;
break;
default:
break;
}
CCLog("pos selected change to : %d", m_ePos);
}
void MyAdListener::onReceiveAd()
{
CCLog("My listener onReceiveAd");
}
void MyAdListener::onPresentScreen()
{
CCLog("My listener onPresentScreen");
}
void MyAdListener::onFailedToReceiveAd(EAdErrorCode code, const char* msg)
{
char logStr[128] = {0};
sprintf(logStr, "My listener onFailedToReceiveAd, error code : %d, message : %s", code, msg);
CCLog(logStr);
}
void MyAdListener::onDismissScreen()
{
CCLog("My listener onDismissScreen");
}

View File

@ -0,0 +1,47 @@
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "AdsAdmob.h"
class MyAdListener : public cocos2d::plugin::AdListener
{
public:
virtual void onReceiveAd();
virtual void onPresentScreen();
virtual void onFailedToReceiveAd(EAdErrorCode code, const char* msg);
virtual void onDismissScreen();
};
class HelloWorld : public cocos2d::CCLayer
{
public:
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();
// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::CCScene* scene();
// a selector callback
void menuCloseCallback(CCObject* pSender);
void testShow(CCObject* pSender);
void testHide(CCObject* pSender);
// option changed callback
void caseChanged(CCObject* pSender);
void posChanged(CCObject* pSender);
// implement the "static node()" method manually
CREATE_FUNC(HelloWorld);
private:
cocos2d::plugin::AdsAdmob* m_pAdmob;
MyAdListener* m_pListener;
cocos2d::CCMenuItemToggle* m_pCaseItem;
cocos2d::CCMenuItemToggle* m_pPosItem;
cocos2d::plugin::ProtocolAds* m_pAds;
cocos2d::plugin::ProtocolAds::EBannerPos m_ePos;
};
#endif // __HELLOWORLD_SCENE_H__

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
<classpathentry exported="true" kind="lib" path="plugin-x/protocols/android/libPluginProtocol.jar"/>
<classpathentry exported="true" kind="lib" path="plugin-x/plugins/admob/android/GoogleAdMobAdsSdk.jar"/>
<classpathentry exported="true" kind="lib" path="plugin-x/plugins/admob/android/libPluginAdmob.jar"/>
</classpath>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>HelloAds</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>Classes</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/Classes</locationURI>
</link>
<link>
<name>plugin-x</name>
<type>2</type>
<locationURI>PARENT-3-PROJECT_LOC/publish</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -0,0 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.cocos2dx.HelloAds" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<uses-feature android:glEsVersion="0x00020000" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:configChanges="orientation" android:label="@string/app_name" android:name=".HelloAds" android:screenOrientation="landscape" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:name="com.google.ads.AdActivity" />
</application>
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

View File

@ -0,0 +1,87 @@
## Prerequisites:
* Android NDK
* Android SDK **OR** Eclipse ADT Bundle
* Android AVD target installed
## Building project
There are two ways of building Android projects.
1. Eclipse
2. Command Line
### Import Project in Eclipse
#### Features:
1. Complete workflow from Eclipse, including:
* Build C++.
* Clean C++.
* Build and Run whole project.
* Logcat view.
* Debug Java code.
* Javascript editor.
* Project management.
2. True C++ editing, including:
* Code completion.
* Jump to definition.
* Refactoring tools etc.
* Quick open C++ files.
#### Setup Eclipse Environment (only once)
**NOTE:** This step needs to be done only once to setup the Eclipse environment for cocos2d-x projects. Skip this section if you've done this before.
1. Download Eclipse ADT bundle from [Google ADT homepage](http://developer.android.com/sdk/index.html)
**OR**
Install Eclipse with Java. Add ADT and CDT plugins.
2. Only for Windows
1. Install [Cygwin](http://www.cygwin.com/) with make (select make package from the list during the install).
2. Add `Cygwin\bin` directory to system PATH variable.
3. Add this line `none /cygdrive cygdrive binary,noacl,posix=0,user 0 0` to `Cygwin\etc\fstab` file.
3. Set up Variables:
1. Path Variable `COCOS2DX`:
* Eclipse->Preferences->General->Workspace->**Linked Resources**
* Click **New** button to add a Path Variable `COCOS2DX` pointing to the root cocos2d-x directory.
![Example](https://lh5.googleusercontent.com/-oPpk9kg3e5w/UUOYlq8n7aI/AAAAAAAAsdQ/zLA4eghBH9U/s400/cocos2d-x-eclipse-vars.png)
2. C/C++ Environment Variable `NDK_ROOT`:
* Eclipse->Preferences->C/C++->Build->**Environment**.
* Click **Add** button and add a new variable `NDK_ROOT` pointing to the root NDK directory.
![Example](https://lh3.googleusercontent.com/-AVcY8IAT0_g/UUOYltoRobI/AAAAAAAAsdM/22D2J9u3sig/s400/cocos2d-x-eclipse-ndk.png)
* Only for Windows: Add new variables **CYGWIN** with value `nodosfilewarning` and **SHELLOPTS** with value `igncr`
4. Import libcocos2dx library project:
1. File->New->Project->Android Project From Existing Code.
2. Click **Browse** button and open `cocos2d-x/cocos2dx/platform/android/java` directory.
3. Click **Finish** to add project.
#### Adding and running from Eclipse
![Example](https://lh3.googleusercontent.com/-SLBOu6e3QbE/UUOcOXYaGqI/AAAAAAAAsdo/tYBY2SylOSM/s288/cocos2d-x-eclipse-project-from-code.png) ![Import](https://lh5.googleusercontent.com/-XzC9Pn65USc/UUOcOTAwizI/AAAAAAAAsdk/4b6YM-oim9Y/s400/cocos2d-x-eclipse-import-project.png)
1. File->New->Project->Android Project From Existing Code
2. **Browse** to your project directory. eg: `cocos2d-x/cocos2dx/samples/Cpp/TestCpp/proj.android/`
3. Add the project
4. Click **Run** or **Debug** to compile C++ followed by Java and to run on connected device or emulator.
### Running project from Command Line
$ cd cocos2d-x/samples/Cpp/TestCpp/proj.android/
$ export NDK_ROOT=/path/to/ndk
$ ./build_native.sh
$ ant debug install
If the last command results in sdk.dir missing error then do:
$ android list target
$ android update project -p . -t (id from step 6)
$ android update project -p cocos2d-x/cocos2dx/platform/android/java/ -t (id from step 6)

View File

@ -0,0 +1,17 @@
# This file is used to override default values used by the Ant build system.
#
# This file must be checked into Version Control Systems, as it is
# integral to the build system of your project.
# This file is only used by the Ant script.
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="HelloAds" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

View File

@ -0,0 +1,78 @@
APPNAME="HelloAds"
# options
buildexternalsfromsource=
usage(){
cat << EOF
usage: $0 [options]
Build C/C++ code for $APPNAME using Android NDK
OPTIONS:
-s Build externals from source
-h this help
EOF
}
while getopts "sh" OPTION; do
case "$OPTION" in
s)
buildexternalsfromsource=1
;;
h)
usage
exit 0
;;
esac
done
# paths
if [ -z "${NDK_ROOT+aaa}" ];then
echo "please define NDK_ROOT"
exit 1
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# ... use paths relative to current directory
PLUGIN_ROOT="$DIR/../../.."
COCOS2DX_ROOT="$DIR/../../../.."
APP_ROOT="$DIR/.."
APP_ANDROID_ROOT="$DIR"
echo "NDK_ROOT = $NDK_ROOT"
echo "COCOS2DX_ROOT = $COCOS2DX_ROOT"
echo "APP_ROOT = $APP_ROOT"
echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT"
# make sure assets is exist
if [ -d "$APP_ANDROID_ROOT"/assets ]; then
rm -rf "$APP_ANDROID_ROOT"/assets
fi
mkdir "$APP_ANDROID_ROOT"/assets
# copy resources
for file in "$APP_ROOT"/Resources/*
do
if [ -d "$file" ]; then
cp -rf "$file" "$APP_ANDROID_ROOT"/assets
fi
if [ -f "$file" ]; then
cp "$file" "$APP_ANDROID_ROOT"/assets
fi
done
# run ndk-build
if [[ "$buildexternalsfromsource" ]]; then
echo "Building external dependencies from source"
"$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
"NDK_MODULE_PATH=${PLUGIN_ROOT}/publish:${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/source"
else
echo "Using prebuilt externals"
"$NDK_ROOT"/ndk-build -C "$APP_ANDROID_ROOT" $* \
"NDK_MODULE_PATH=${PLUGIN_ROOT}/publish:${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt"
fi

View File

@ -0,0 +1,22 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cocos2dcpp_shared
LOCAL_MODULE_FILENAME := libcocos2dcpp
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
LOCAL_WHOLE_STATIC_LIBRARIES += cocos2dx_static \
PluginProtocolStatic PluginAdmobStatic
include $(BUILD_SHARED_LIBRARY)
$(call import-module,cocos2dx)
$(call import-module,protocols/android)
$(call import-module,plugins/admob/android)

View File

@ -0,0 +1,2 @@
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1

View File

@ -0,0 +1,46 @@
#include "AppDelegate.h"
#include "cocos2d.h"
#include "CCEventType.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>
#include "PluginJniHelper.h"
#define LOG_TAG "main"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
using namespace cocos2d;
extern "C"
{
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JniHelper::setJavaVM(vm);
PluginJniHelper::setJavaVM(vm); // for plugins
return JNI_VERSION_1_4;
}
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
{
if (!CCDirector::sharedDirector()->getOpenGLView())
{
CCEGLView *view = CCEGLView::sharedOpenGLView();
view->setFrameSize(w, h);
AppDelegate *pAppDelegate = new AppDelegate();
CCApplication::sharedApplication()->run();
}
else
{
ccDrawInit();
ccGLInvalidateStateCache();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
CCTextureCache::reloadAllTextures();
CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
CCDirector::sharedDirector()->setGLDefaultValues();
}
}
}

View File

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# 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 *;
#}

View File

@ -0,0 +1,13 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-13
android.library.reference.1=../../../../cocos2dx/platform/android/java

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">HelloAds</string>
</resources>

View File

@ -0,0 +1,52 @@
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
package org.cocos2dx.HelloAds;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.plugin.PluginWrapper;
import android.os.Bundle;
public class HelloAds extends Cocos2dxActivity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
PluginWrapper.init(this); // for plugins
PluginWrapper.setGLSurfaceView(Cocos2dxGLSurfaceView.getInstance());
}
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// HelloAds should create stencil buffer
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
return glSurfaceView;
}
static {
System.loadLibrary("cocos2dcpp");
}
}

View File

@ -3,7 +3,7 @@
<!-- link jar files -->
<property name="myjar.libs.dir" value="./sdk" />
<target name="-pre-build" depends="check-dependens">
<target name="-pre-compile" depends="check-dependens">
<if condition="${jarExisted}">
<then>
<path id="project.all.jars.path">

View File

@ -1,6 +1,7 @@
#define plugins array
export ALL_PLUGINS=("flurry" "umeng" \
"alipay" "nd91")
"alipay" "nd91" \
"admob")
# define the plugin root directory & publish target directory
export TARGET_DIR_NAME="publish"