天天看點

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

考慮到以下兩點:

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進行添加。最終運作後效果如下圖所示:

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

從效果圖中可以看出我們已經在AndroidManifest.xml裡把橫屏改成了豎屏。(這個圖檔沒有更新,更新後廣告條左上角會有一個叉叉,用來關閉廣告)。

水準有限,如有不妥,歡迎指正!

參考文獻:

[1]廣點通官方示例代碼。

[2]http://blog.csdn.net/u014078216/article/details/48931565