Hack your way to Cocos SDKBox Plugin development

Hack your way to SDKBox for plugin development

  • This guide is for those who need to develop cocos/sdkbox plugins.
  • This is only for testing, if you want to be able to to use sdkbox import myPlugin you have to reach out to cocos/sdkbox team and ask them to test and include your plugin on their repositories.
  • I only tested Cpp Plugin on Android
  • I tested all codes in a machine that runs linux Mint
  • The only way I could get this to work was to switch back to java 1.7
  • Hope is usefull to others..

Create a new project, compile it and check it is working

cocos new -l cpp -d . -p org.cocos2dx.myPluginTester myPluginTester
cd myPluginTester
cocos compile -p android --android-studio

I am using Android Studio to test my app you can use console by removing –android-studio

Open myPluginTester/proj.android-studio as project on Android Studio and run to confirm that you see cocos Hello World App running on your phone or simulator.

Add sdkbox essentials to your project

What I did to setup sdkbox is to import another supported plugin and remove the not needed stuff by reversing the plugins manual installation steps found on sdkbox web page for the plugin.

Using iap

You may use any of the official plugins

sdkbox import iap

Now compile and run a simulation to be sure that teh iap plugin

cocos compile -p android --android-studio

In Android Studio run project opened in the previous step, you should see the same thing in your device.

Based on iap manual install steps for android found on sdkbox documentation web page

Remove jar PluginGooglePlay.jar and PluginIAP.jar.

Skipping this step causes no problem at all but only keeping some unused files in your project.

The jar files location is
Android command-line: cocos2d/cocos/platform/android/java/libs
Android Studio: cocos2d/cocos/platform/android/libcocos2dx/libs

Remove permissions from AndroidManifest.xml

Skipping this step causes no problem at all but only keeping some unneeded permition tags.

Remove these tags added by sdkbox import iap to AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.android.vending.BILLING"/>

Edit and clean up Android.mk Important Step!

Android.mk is located in
Android command-line: proj-android/jni/
Android Studio: proj.android-studio/app/jni/

Remove or comment line

LOCAL_WHOLE_STATIC_LIBRARIES += PluginIAP

and line

$(call import-module, ./pluginiap)

* Edit and clean up project.properties*

The project.properties file location is
Android command-line: ./proj.android/project.properties
Android Studio: ./proj.android-studio/app/project.properties

Remove or comment line (based on the Android Studio Version)

android.library.reference.1=../../../Android/Sdk/extras/google/google_play_services/libproject/google-play-services_lib/

Remove plugin include from AppDelegate.cpp

AppDelegate.cpp is located in ./Classes folder

Remove or comment line

#include "PluginIAP/PluginIAP.jar"

also remove or comment line (~line 41)

sdkbox::IAP::init();

pluginIAP removed!

Just to be sure compile and test the app!

Now myPluginTester cocos project initializes sdkbox athought it does not do anything else!

Create a plugin using sdkbox.jar on Intellij Idea

I am new to Java and Mobile App development and I dont really like nor understand most of this shit or why it has to be so complicated to setup. But my java-mobile-app-idea guru told me to do it! So dont ask cause I know as mush as you understand from these steps.

  • Create new Project named PluginMyPlugin
  • Create a class file in projects src folder named MyPlugin containing
public class MyPlugin { }
  • Go to File -> Project Structure -> Project Settings -> Project

    • Set Project SDK to Android API 7 Platform
    • Set Project language level to 6 – @Override in interfaces
    • Remember the Project compiler output is where the plugin jar will be found.
  • Go to File -> Project Structure -> Project Settings -> Modules

    • Got to Dependencies tab
    • Use the green + sign to add JARs or Directories..
    • find and add sdkbox.jar from myPluginTester cocos project ./cocos2d/cocos/platform/android/libcocos2dx/libs/sdkbox.jar
    • Check the export checkbox left of the sdkbox.jar
    • change Scope to Provided
  • Go to File -> Project Structure -> Project Settings -> Libraries and make sure it empty

  • Go to File -> Project Structure -> Project Settings -> Artifacts

    • Use the green + sign on the top left to create a JAR -> From modules with dependencies.. artifact
    • Set MainClass by selecting and from Project tab select MyPlugin.java class file created in step 2

      You ll get an error saying MyPlugin is not acceptable just click ok
      An then hit cancel
      Magically the name is inserted..

    • hit OK

      Any error saying that MANIFEST.MF exists means you have to delete that file from src/META-INF folder and repeat this step!

  • Just to be sure do a test Build -> Build Artifacts.. and at the other menu that opens hit build

  • import sdkbox and intent

import com.sdkbox.plugin.SDKBox; 
import com.sdkbox.plugin.PluginListener;
import android.content.Intent;
  • Make MyPlugin class implement PluginListener
package org.cocos2dx.plugin;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.sdkbox.plugin.SDKBox;
import com.sdkbox.plugin.PluginListener;

public class MyPlugin implements PluginListener {

    private static Activity sActivity = null;
    private static Context sContext = null;
    private static MyPlugin sAdapter = null;

    public MyPlugin(Context context) {

        sActivity = (Activity) context;
        sContext = context;

        SDKBox.addListener(this);

        Log.d("MyPlugin","MyPlugin created");
        Log.d("MyPlugin","processName: "+SDKBox.getContext().getApplicationInfo().processName);
    }

    public static void init()
    {
        Log.d( "MyPlugin", "Initialize plugin.." );

        if(sActivity==null)
        {
            sAdapter = new MyPlugin(SDKBox.getContext());
        }
    }


    public boolean onActivityResult(int requestCode, int resultCode, Intent data)
    {
        Log.d( "MyPlugin", "onActivityResult");
        return true;
    }

    public boolean onBackPressed()
    {
        Log.d( "MyPlugin", "onBackPressed" );
        return true;
    }

    public void onDestroy()
    {
        Log.d( "MyPlugin", "onDestroy" );
        SDKBox.removeListener(this);
    }

    public void onPause()
    {
        Log.d( "MyPlugin", "onPause" );
        SDKBox.removeListener(this);
    }

    public void onResume()
    {
        Log.d( "MyPlugin", "onResume" );
        SDKBox.removeListener(this);
    }

    public void onStop()
    {
        Log.d( "MyPlugin", "onStop" );
        SDKBox.removeListener(this);
    }

    public void onStart()
    {
        Log.d( "MyPlugin", "onStart" );
        SDKBox.removeListener(this);
    }

}

Copy PluginMyPlugin.jar to cocos project

If the artifacts are build the PluginMyPlugin.jar is in ./out folder check step 3 to find Project compiler output. Copy jar to
Android command-line: cocos2d/cocos/platform/android/java/libs
Android Studio: cocos2d/cocos/platform/android/libcocos2dx/libs

Create Cpp Wrapper!

mkdir Classes/MyPLugin
touch Classes/MyPLugin/MyPlugin.h
touch Classes/MyPLugin/MyPlugin.cpp

Create file MyPlugin.h

#ifndef __MYPLUGIN_H__
#define __MYPLUGIN_H__

#include "cocos2d.h"
#include "Sdkbox.h"
#include "platform/android/jni/JniHelper.h"

namespace sdkbox
{
    class MyPlugin
    {
        public:

            static MyPlugin* getInstance();


        private:
            MyPlugin();

            static MyPlugin* instance;

            virtual ~MyPlugin();
    };
}
#endif //__MYPLUGIN_H__

Create file MyPlugin.cpp

#include "MyPlugin.h"

using namespace cocos2d;
using namespace sdkbox;

const char * JavaBaseClass="org/cocos2dx/plugin/MyPlugin";

MyPlugin* MyPlugin::instance=NULL;

MyPlugin::MyPlugin()
{
    log( "MyPlugin()" );
}

MyPlugin::~MyPlugin()
{
    log( "~MyPlugin()" );
}

MyPlugin* MyPlugin::getInstance()
{
    if (instance==NULL)
    {
        instance = new MyPlugin();

        JNIEnv* env;
        env = JniHelper::getEnv();

        jclass mypluginclass = env->FindClass ( JavaBaseClass );

        if ( mypluginclass == NULL )
        {
            log ("Unable to find java class %s", JavaBaseClass);        
        }
        else
        {
            jmethodID javaMethod = env->GetStaticMethodID ( mypluginclass,"init", "()V" );

            if (javaMethod == NULL )
            {
                log ( "Unable to find static java method init" );
            }
            else
            {
                env->CallStaticVoidMethod ( mypluginclass, javaMethod );
            }
        }
    }
    return instance;
}

Include Cpp Wrapper in Android.mk

Edit Android.mk file located in
Android command-line: proj-android/jni/
Android Studio: proj.android-studio/app/jni/

In Android use ../../ instead of ../../../ which is for Android Studio

Add line

LOCAL_SRC_FILES += ../../../Classes/MyPlugin/MyPlugin.cpp

after the other LOCAL_SRC_FILES

Add line

LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../Classes/MyPlugin

after the other LOCAL_C_INCLUDES

Edit AppDelegate.cpp to initialize the plugin

Include MyPlugin.h

#include "MyPlugin.h";

Initialize the pugin

Before anything else in function AppDelegate::applicationDidFinishLaunching() add this line

sdkbox::MyPlugin::getInstance();

Code should look like this.

bool AppDelegate::applicationDidFinishLaunching() {
    sdkbox::MyPlugin::getInstance();
    ...
}

You may use sdkbox::MyPlugin::getInstance()-><function_name>() to call any plugin function you may create.

Thats it!

Compile and run and check the logcat logs..