Add plugin admob for android platform.

This commit is contained in:
zhangbin 2013-04-22 10:40:29 +08:00
parent 79870ded6a
commit 6a48e8145d
15 changed files with 625 additions and 0 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();
}
}
}