Plugin-X Admob Cocos2d-x 3

My git hub repository using new api(Google Play services version) ^^

1 Like

I added AdMob on Android and iOS by hand (not using the plugin), as this was easier to do the trying to get the plugin working. There is either no or seriously outdated documentation available for the plugin, which imo renders it pretty useless. You can build the best piece of software, but if no one knows how to use itā€¦

The help on the google pages is pretty good on the other hand, plus you find tons of tutorials out there for iOS and Android to help you further along.

We have a working android build with admob added directly. But we want to have it with plugin-x support, because when adding it directly it needs to be readded when the engine is updated. We would love to have working plugin-x because the update process would only need ā€œbuildingā€ plugin-x again.

I understand why the plugin would be nice to use, as you donā€™t have to maintain Android and iOS code yourself.

Just for my curiosity, why do you need to re-add it after updating cocos? Is it because you added it to the main activity of cocos? Because if that is the case, I can be of assistanceā€¦

The admob-stuff needs some changes in the mainmain activity of cocos, yes. This file could change from version to version. I think itā€™s annoying to make the changed after every update of the engine.

What do you have in mind?

The way to solve this once and for all is by implementing your own main activity, that overrides all the necessary functions. You add you AdMob code to your own main activity, and updating cocos wonā€™t effect any of your changes.

Here is an example:

package com.replacewithyourcompanyname.replacewithyourgamename;

import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;

import org.cocos2dx.plugin.PluginWrapper;
import org.cocos2dx.plugin.FacebookWrapper;

// Explanation: The actual AdMob, Google Analytics and Billing code is nicely packed away in their own classes,
//              I put them in a library folder as they are the same for all games.
import com.replacewithyourcompanyname.library.ads.AdMob;
import com.replacewithyourcompanyname.library.analytics.Analytics;
import com.replacewithyourcompanyname.library.inappstore.GoogleBilling;

import android.content.Intent;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;


public class ReplaceWithGameName extends Cocos2dxActivity
{
    ////////////////////////////////////////////////////////////////////////////////
    // Member variables
    ////////////////////////////////////////////////////////////////////////////////
    // Explanation: I know only the AdMob class applies to your situation,
    //              but I bet you have more changes then just AdMob,
    //              therefor I left the other 2 as examples.
    private AdMob            m_adMob;
    private Analytics        m_analytics;
    private GoogleBilling    m_googleBilling;


    ////////////////////////////////////////////////////////////////////////////////
    // Constructor
    ////////////////////////////////////////////////////////////////////////////////
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        // Attach volume controls to media volume
        setVolumeControlStream( AudioManager.STREAM_MUSIC );

        // Explanation: I left this code here, so you can see how to initialize PluginX and for example the Facebook plugin
        // Init the plugin
        PluginWrapper.init(this);
        PluginWrapper.setGLSurfaceView( Cocos2dxGLSurfaceView.getInstance() );
        // Init the facebook plugin
        FacebookWrapper.onCreate(this);

        // Explanation: Here your initialize your own components.
        //              If your AdMob class is generic, you should also pass in the Admob banner ID here.
        // Initialize library components
        m_adMob         = new AdMob();          m_adMob.Initialize(this);
        m_analytics     = new Analytics();      m_analytics.Initialize(this);
        m_googleBilling = new GoogleBilling();  m_googleBilling.Initialize(this, Cocos2dxGLSurfaceView.getInstance());
    }


    ////////////////////////////////////////////////////////////////////////////////
    // Plugin handling
    ////////////////////////////////////////////////////////////////////////////////
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        boolean handledByPlugin            = PluginWrapper.onActivityResult(requestCode, resultCode, data);
        boolean handledByGoogleBilling    = m_googleBilling == null ? false : m_googleBilling.onActivityResult(requestCode, resultCode, data);
        FacebookWrapper.onAcitivityResult(requestCode, resultCode, data);
        // Pass on to parent if not handled
        if (!handledByPlugin && !handledByGoogleBilling)  { super.onActivityResult(requestCode, resultCode, data); }
    }


    @Override
    public void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
        FacebookWrapper.onSaveInstanceState(outState);
    }


    ////////////////////////////////////////////////////////////////////////////////
    // Functions
    ////////////////////////////////////////////////////////////////////////////////
    public void finish()
    {
        super.finish();
        // Kill the process, otherwise the app sometimes hands with a black screen on restart
        android.os.Process.killProcess( android.os.Process.myPid() );
    }


    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        if (m_adMob != null)    { m_adMob.onConfigurationChanged(newConfig); }
    }


    @Override
    protected void onStart()
    {
        super.onStart();
        if (m_analytics != null)    { m_analytics.onStart(); }
    }

    
    @Override
    protected void onStop()
    {
        super.onStop();
        if (m_analytics != null)    { m_analytics.onStop(); }
    } 


    @Override
    public void onResume()
    {
        super.onResume();
        if (m_adMob != null)    { m_adMob.onResume(); }
    }


    @Override
    public void onPause()
    {
        if (m_adMob != null)    { m_adMob.onPause(); }
        super.onPause();
    }


    @Override
    public void onDestroy()
    {
        if (m_adMob != null)            { m_adMob.onDestroy(); }
        if (m_googleBilling != null)    { m_googleBilling.onDestroy(); }
        super.onDestroy();
    }
}

As you can see, not all classes need all functionality forwarded.
What needs what you can find in the respective SDKs (in the above exampe for AdMob, Google Analytics, Google Billing).

The important thing is that you now have an abstraction layer between cocos and your game, and you can do whatever you want/need here, without effecting the original cocos sourceā€¦

Hope this helps!

Kind regards,
Michaƫl

Thanks, thats a nice way of achieving this.
Unfortunately we also need lua bindings and plugin-x is providing this ^^

We have a working version with own implementation and lua-bindings but we have a jni bug. I thought that we could use plugin-x instead but yeahā€¦ I think itā€™s easier to fix the own bug instead of using this, sorry, mess.

Our Cocos Helper has AdMob support https://github.com/SonarSystems/Sonar-Cocos-Helper