您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-x 3.X, Android Studio版添加广点通广告平台

2015-10-21 15:23 507 查看
考虑到以下两点:
1. Cocos2d-x从3.7版开始优化对Android Studio的支持,相信这一趋势还会继续。可惜目前相关帮助文档还不完善,很多东西需要自己摸索。
2. 广点通广告平台的官方帮助文档没有针对Cocos2d-x。
所以在此对自己所学所得做一些总结,也希望能帮助到那些处在摸索之中的朋友们。

本文所用cocos2d-x为3.8版,android studio为1.3.2版,广点通SDK为4.8版。(插播广告:如需添加IOS版广告平台请戳这里

准备工作:

1)进入广点通官网,注册账号。注册时需要上传身份证正反面照片(好像还需要手持身份证照片)以及银行账户。然后等待审核。广点通审核时间略长,大概要一个礼拜。

2)审核通过后就可以创建应用和广告位。

3)下载广点通安卓版SDK。广点通的SDK文件夹里有示例代码,可以打开看一看,官网上也帮助文档,但是没有针对Cocos2d-x的。

开干正事:

1)在搞懂如何添加之前,建议不要直接在自己的工程里添加,最好新建一个HelloWorld项目用于试验。关于如何新建一个Android Studio版的HelloWorld项目,请参考博主另一篇博文

2)打开下载下来的广点通文件夹,复制其中的GDTUnionSDK.4.8.509.jar文件,并拷贝到新建的HelloWorld项目下proj.android-studio->app->libs->armeabi文件夹中(该文件夹只有在第一步中完成编译之后才会出现)。并在Android Studio中打开HelloWorld项目,找到GDTUnionSDK.4.8.509.jar(在jiniLibs->armeabi下面),右击,选择Add
As Library。这样就把广点通SDK添加到我们的项目中了。

3)在Android Studio中打开AndroidManifest.xml文件,往里面添加广点通权限声明和Activity声明。添加完后完整代码如下所示:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.istudy.HelloWorldGDT"
android:installLocation="auto">

<!--广点通声明1开始-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--广点通声明1结束-->

<uses-feature android:glEsVersion="0x00020000" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher">

<!-- Tell Cocos2dxActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="cocos2dcpp" />

<!--广点通声明2开始-->
<service
android:name="com.qq.e.comm.DownloadService"
android:exported="false" >
</service>

<activity
android:name="com.qq.e.ads.ADActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" >
</activity>
<!--广点通声明2结束-->

<activity
android:name="org.cocos2dx.cpp.AppActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"
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>
</application>

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

</manifest>

4)在Android Studio里打开AppActivity,往里面添加显示广告的Java代码。但是由于我们Cocos2d-x的场景都是用C++实现的,所以我们在这里需要利用Handler来做接口。这和官方帮助文档不同。添加完后完整代码如下所示:

AppActivity

package org.cocos2dx.cpp;

import org.cocos2dx.lib.Cocos2dxActivity;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.qq.e.ads.banner.ADSize;
import com.qq.e.ads.banner.AbstractBannerADListener;
import com.qq.e.ads.banner.BannerView;

public class AppActivity extends Cocos2dxActivity {

//声明应用ID
public static final String APPID = "1101152570";

//声明广告条容器,广告条和广告位ID
private static RelativeLayout bannerContainer;
BannerView bv;
public static final String BannerPosID="9079537218417626401";

//声明handler用于发送消息
private static Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

//创建广告条容器
bannerContainer = new RelativeLayout(this);
RelativeLayout.LayoutParams parentLayoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
this.addContentView(bannerContainer, parentLayoutParams);

//加载或卸载广告
handler = new Handler() {
@Override
public void handleMessage(Message msg) {

switch (msg.what) {
case 0:// showBannerAd()
if (bannerContainer.getChildCount() == 0) {
//初始化并加载广告条
initBanner();
bv.loadAD();

}else{
if (bv != null) {
bv.setVisibility(View.VISIBLE);
bv.loadAD();
}
}
break;
case 1: //hideBannerAd()
if (bv != null) {
doCloseBanner();
}
break;

default:
break;

}
}

};

}

private void initBanner() {
bv = new BannerView(this, ADSize.BANNER, APPID, BannerPosID);
bv.setRefresh(30);
bv.setShowClose(true);//一定要有这个关闭按钮,否则某些应用商店不给通过,虽然官方示例代码中没有。本人就被坑过一次。
bv.setADListener(new AbstractBannerADListener() {

@Override
public void onNoAD(int arg0) {
Log.i("AD_DEMO", "BannerNoAD,eCode=" + arg0);
}

@Override
public void onADReceiv() {
Log.i("AD_DEMO", "ONBannerReceive");
}
});
//添加广告并设置它的位置
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
//layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
bannerContainer.addView(AppActivity.this.bv, layoutParams);

}

//刷新
private void doRefreshBanner() {
if (bv == null) {
initBanner();
}
bv.loadAD();
}

//关闭
private void doCloseBanner() {
bannerContainer.removeAllViews();
bv.destroy();
bv = null;
}

//打开和关闭广告接口
public static void showBannerAd() {
handler.sendEmptyMessage(0);
}
public static void hideBannerAd() {
handler.sendEmptyMessage(1);
}

}
注意我们这里是用代码来创建一个RelativeLayer布局对象来作为广告条容器的,而非通过布局文件xml来实现的,这一点和官方文档也不同。

5)在Cocos2d-x的Classes下面新建一个类,命名为GDTAD,在里面通过jni把Java的广告开关转换成了C++函数,以便在Cocos2d-x场景里调用。完整代码如下:

GDTAD.h

#ifndef CLASSES_GDTAD_H
#define CLASSES_GDTAD_H

class GDTAD {
public:
static void showBannerAd();
static void hideBannerAd();

};

#endif //CLASSES_GDTAD_H


GDTAD.cpp

#include "GDTAD.h"
#include "cocos2d.h"

USING_NS_CC;

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/jni/JniHelper.h"
#include <jni.h>

const char* AppActivityCalssName = "org/cocos2dx/cpp/AppActivity";

//显示广告条
void GDTAD::showBannerAd()
{
cocos2d::JniMethodInfo showBanner;
if (cocos2d::JniHelper::getStaticMethodInfo(showBanner, AppActivityCalssName, "showBannerAd", "()V")) {
showBanner.env->CallStaticVoidMethod(showBanner.classID, showBanner.methodID);
}
else{
log("jni:showBannerStatic false");
}
}

//隐藏广告条
void GDTAD::hideBannerAd()
{
cocos2d::JniMethodInfo hideBanner;
if (cocos2d::JniHelper::getStaticMethodInfo(hideBanner, AppActivityCalssName, "hideBannerAd", "()V")) {
hideBanner.env->CallStaticVoidMethod(hideBanner.classID, hideBanner.methodID);
}
else{
log("jni:hideBannerStatic false");
}
}

#else

//广告条
void GDTAD::showBannerAd()
{
log("showBannerAd() called");
return;
}

void GDTAD::hideBannerAd()
{
log("hideBannerAd() called");
return;
}

#endif

6)接下来就可以愉快的在Cocos2d-x场景里添加广告了。这里我们在HelloWorld场景的最上端添加一个广告条,完整代码如下

HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include "GDTAD.h"

class HelloWorld : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();

virtual bool init();

// a selector callback
void menuCloseCallback(cocos2d::Ref* pSender);

// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__


HelloWorldScene.cpp

#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();

// 'layer' is an autorelease object
auto 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 ( !Layer::init() )
{
return false;
}

Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();

/////////////////////////////
// 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
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y + closeItem->getContentSize().height/2));

// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);

/////////////////////////////
// 3. add your codes below...

//添加广告条
GDTAD::showBannerAd();

// add a label shows "Hello World"
// create and initialize a label

auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);

// position the label on the center of the screen
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - label->getContentSize().height));

// add the label as a child to this layer
this->addChild(label, 1);

// add "HelloWorld" splash screen"
auto sprite = Sprite::create("HelloWorld.png");

// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

// add the sprite as a child to this layer
this->addChild(sprite, 0);

return true;
}

void HelloWorld::menuCloseCallback(Ref* pSender)
{
Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif

}

7)编译并运行。在编译之前需要在Android.mk文件里面添加GDTAD.cpp的路径,否则新建的C++文件无法被编译进来。比如我这里可以输入vi ~/Documents/HelloWorld/proj.android-studio/app/jni/Android.mk进行添加。最终运行后效果如下图所示:



从效果图中可以看出我们已经在AndroidManifest.xml里把横屏改成了竖屏。(这个图片没有更新,更新后广告条左上角会有一个叉叉,用来关闭广告)。

水平有限,如有不妥,欢迎指正!

参考文献:

[1]广点通官方示例代码。

[2]http://blog.csdn.net/u014078216/article/details/48931565
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息