Sunday, March 10, 2013

Shards - Work In Progress I



This is short info on our upcoming game - Shards - we are working on. The game will be clone of well known arcade classic with glassy look and very nice fractal backgrounds. The music in video is just a placeholder I found on the web - it sounds to make me sure the sound engine works.


 Making the game we are using these technologies:
  • box2D for physics,
  • notice the usage of our universal box2D debug draw that works for Open GL ES 1.x and 2.0,
  • our cross platform engine -  the video is taken from desktop Windows while the game runs on Android as well,
  • PicOpt - our sprite atlas creation tool that is free to download,
  • for Android NDK: textures are loaded through this way, while sound (not too much of them in the game presently) is coded like this,
  • for ads we plan to utilize our simple ads manager.

Tuesday, March 5, 2013

Creating Ads Manger for Android - Part 5 - Implementing Leadbolt





previous parts

 In previous part we implemented Madvertise. This time we will do the same with Leadbolt. While AdMob and Madvertise pays you for click, Leadbolt pays you usually for action the user has to do. So you may encounter CPA term which stands for Cost per Action instead well known CPC (cost per Click). If I convert my latest revenue to CPC I get very low value 0.01 - 0.02 while AdMob is 0.035 in average. Beside this Zone Alarm for Android is warning users that your app contains AdwareAndroidos.leadbold... Is it still worth to implement it? Ok, I am using only banners, not any kind of ads like push notifications and so on, so my users will not get angry. The app passed registration at Slideme.org or Amazon.com without problems. And the size of the banner is smaller than AdMob or Madvertise banners. Thus, for our game Deadly Abyss 2 is Leadbolt only network if playing on mobile phone (if playing on tablet then AdMob, Madvertise and Leadbolt are rotating).
 Finally, we are making ad manager to handle multiple networks, so it is not wise to rely only on one network.
 If you intent to use Leadbolt you can register through this link. If you do so, I will get some small reward from them :-)

Adding Leadbolt SDK

 This should be no problem. Leadbolt has very good and simple manual. It is located under App Developer SDKs in HELP/FAQS section. Actually it is the same as AdMob integration - copy .jar with SDK into libs folder and then adjust Build Path in Project Properties (right click on project name in Eclipse). Then Add JARs...


Adjusting manifest

 As for previous ad networks we have to adjust manifest file with permissions. Leadbolt has three required permissions: INTERNET, ACCESS_NETWORK_STATE and READ_PHONE_STATE. The first two we already have from times of AdMob implementation. There are three optional permissions: ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION and ACCESS_ LOCATION_EXTRA_COMMANDS. The coarse location we already allowed for Madvertise so we adjust the manifest like this:

  <!-- additional LeadBolt permissions -->
  <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
  <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/> 


Adjusting constatns

 While most of the other networks has some way how to set refresh rate for Leadbolt you have to do it by yourself. So in the file with constants (SBCAdsConstatnts.java) we will define these lines:

 // Leadbolt
 public static final String LEADBOLT_UNIT_ID = "YOUR_LEADBOLT_ID_HERE";
 public static final long LEADBOLT_REFRESH_RATE = 1000 * 90 * 1;

 The first line contains the ID your ad unit is assigned by Leadbolt. The second line defines refresh rate in millis - here 1,5 minute.


LeadboltSystem.java

 Now let's start implementation. As usual the imports and fields come first:

package com.sbcgames.sbcads;import com.pad.android.iappad.AdController;import com.pad.android.listener.AdListener;import com.sbcgames.sbcengine.SBCEngine;import android.util.Log;import android.view.KeyEvent;import android.view.ViewGroup;public class LeadboltSystem implements SBCAdSystem, AdListener
{
 private final String SYSTEM_NAME = "LEADBOLT ";
 private SBCAdEventListener mListener = null;
 private AdController mAdView;
 private final ViewGroup mLayout;
 private Runnable mR = null;
 private SBCEngine mSBCEngine = null;

 The constructor is very simple:

 // ------------------------------------------------------------------------
 public LeadboltSystem(SBCEngine aSBCEngine, ViewGroup aLayout)
 {
  mSBCEngine = aSBCEngine;
  mLayout = aLayout;
 }


SBCAdSystem implementation

 Next follows implementation of our SBCAdSystem interface:

 //------------------------------------------------------------------------
 // SBCAdSystem
 //------------------------------------------------------------------------
 @Override
 public void start()
 {
  final LeadboltSystem system = this;

  mR = new Runnable()
  {
   public void run()
   {
    Log.d("AdsSystem", SYSTEM_NAME + "Creating AdController and asking for Ad");

    if (mAdView != null)
    {
     stop();
     destroy();
     mAdView = null;
    }
    
    mAdView = new AdController(mSBCEngine, SBCAdsConstants.LEADBOLT_UNIT_ID, system);
    mAdView.loadAd();
    
    mLayout.postDelayed(this, SBCAdsConstants.LEADBOLT_REFRESH_RATE);
   }
  };

  mLayout.postDelayed(mR, 0);
 }

 Here is problem that I encountered: to refresh ad, calling to destroyAd() (called in destroy() method) and then calling to loadAd() should be enough. But the refreshing in this way did not work for me. So I am destroying the mAdView (the AdController object) every time and creating new one. I posted question to forum and I got reply from user called jay-z. While the above method works, I will try his code and update this article accordingly if it will work for me too.

 Here is implementation of next methods - nothing special here:

 //------------------------------------------------------------------------
 @Override
 public void stop()
 {
  if (mR != null)
  {
   Log.d("AdsSystem", SYSTEM_NAME + "removing listener");
   mLayout.removeCallbacks(mR);
  }
 }

 //------------------------------------------------------------------------
 @Override
 public void destroy()
 {
  if (mAdView != null)
  {
   mAdView.destroyAd();
  }
 }

 //------------------------------------------------------------------------
 @Override
 public void setEventListener(SBCAdEventListener aListener)
 {
  mListener = aListener;
 }

 In last two parts when implementing AdMob and Madvertise we left our keyDown implementation empty. For Leadbolt we have to handle back key. This is the reason why we have this method in interface. Of course, to avoid implementation in every ad system we could create abstract class between interface and concrete implementation (that will do nothing) and override it only when we need specialised behavior - I will leave this small change on your choice:

 //------------------------------------------------------------------------
 @Override
 public boolean keyDown(final int aKeyCode, final KeyEvent aEvent)
 {
  if (aKeyCode == KeyEvent.KEYCODE_BACK)
  {
   if (mAdView.onBackPressed())
   {
    Log.d("AdsSystem", SYSTEM_NAME + "back key pressed");
    return true;
   }
  }
  
  return false;
 }


AdListener implementation

 Leadbolt, as well as other ad networks we have seen so far has its own interface for callbacks. The name is AdListener - the same as for AdMob. But this time it has different set of methods. Their implementation is empty for most of the them. The one that is important is onAdClicked(). Despite AdMob or Madvertise, the Leadbolt does not start any new Activity that would pause your current activity - your game. So, you have to do it by yourself. We are calling sendMessage() method. This method is general method in my engine to send messages to Java part of the engine from other Java parts or from NDK. Thanks to this I can ask engine to do lot of things just with different method's arguments.

 //------------------------------------------------------------------------
 // LEADBOLT
 //------------------------------------------------------------------------
 @Override
 public void onAdClicked()
 {
  stop();
  mSBCEngine.sendMessage(SBCEngine.MESSAGE_OUT_PAUSE, 0, 0);
  Log.d("AdsSystem", SYSTEM_NAME + "onAdClicked");
 }
 
 //------------------------------------------------------------------------
 @Override
 public void onAdAlreadyCompleted()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdAlreadyCompleted");
 }
  
 //------------------------------------------------------------------------
 @Override
 public void onAdClosed()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdClosed");
 }

 //------------------------------------------------------------------------
 @Override
 public void onAdCompleted()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdCompleted");
 }

 //------------------------------------------------------------------------
 @Override
 public void onAdFailed()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdFailed");
  mListener.onFailed(this);
 }

 //------------------------------------------------------------------------
 @Override
 public void onAdHidden()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdHidden");
 }

 //------------------------------------------------------------------------
 @Override
 public void onAdLoaded()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdLoaded");
 }

 //------------------------------------------------------------------------
 @Override
 public void onAdPaused()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdPaused");
 }

 //------------------------------------------------------------------------
 @Override
 public void onAdProgress()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdProgress");
 }

 //------------------------------------------------------------------------
 @Override
 public void onAdResumed()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdResumed");
 }}


Conclusion

 This is all for Leadbolt implementation. This was also last part of this little series. We created simple but extensible ad manager. Now it is up to you to enhance it and add other ad networks.



Sunday, March 3, 2013

Creating Ads Manger for Android - Part 4 - Implementing Madvertise





previous parts


Last time we implemented first ad network - AdMob. Today we will add Madvertise. This network is exactly the reason why we are building some ad systems manager. It seems that Madvertise is focused on some countries of western Europe - Germany, Italy. Earnings are about 0,05 EUR / click, which is not bad. But if your user is in any other location they will not send an ad into his device. This results into low fill rate but if you have ad manager you can just say never mind and skip to other ad network.


Adding Madvertise SDK

 To integrate Madvertise SDK into your Eclipse project follow the instructions here. It is enough to follow the instructions until you added Madvertise project into your project as rest may be little bit different for out adds manager.


Adjusting manifest

 Last time we already added permissions for INTERNET and ACCESS_NETWORK_STATE. Today we will add optional permissions for reading state of wifi and to roughly detect the location of the user.

    <!-- additional Madvertise permissions -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

 Next we need to adjust the manifest file with Madvertise activity. There is also place for token identifying your app. If you just want to test then put word "TestTokn" there. Do not forget to replace it when you are ready to publish.

        <activity android:name="de.madvertise.android.sdk.MadvertiseActivity" />

        <!-- Setup your site token. For tests, use 'TestTokn' -->
        <meta-data
            android:name="madvertise_site_token"
            android:value="TestTokn" />


Adjusting constants

 When implementing AdMob we had to adjust file SBCAdsConstants.java with AdMob ad unit ID. This is not necessary here as we put our Madvertise ad ID directly into manifest file.


MadvertiseSystem.java

 Now  we are ready to implement the class. We start with imports and variables again:

package com.sbcgames.sbcads;

import com.sbcgames.sbcengine.SBCEngine;

import de.madvertise.android.sdk.MadvertiseView;
import de.madvertise.android.sdk.MadvertiseView.MadvertiseViewCallbackListener;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;

public class MadvertiseSystem implements SBCAdSystem, MadvertiseViewCallbackListener
{
 private final String SYSTEM_NAME = "MADVERTISE ";
 private SBCAdEventListener mListener = null;
 private MadvertiseView mAdView;
 private ViewGroup mLayout;

 Instead of AdMob AdListener we are implementing MadvertiseViewCallbackListener this time. SBCAdSystem is our interface that we have to implement for every ad network we want our ad manager to handle. This is the constructor:

 // ------------------------------------------------------------------------
 public MadvertiseSystem(SBCEngine aSBCEngine, ViewGroup aLayout)
 {
  mLayout = aLayout;

  // new view - all defaults
  mAdView = new MadvertiseView(aSBCEngine.getApplicationContext());

  // set the AdListener.
  mAdView.setMadvertiseViewCallbackListener(this);
  
  // Add the AdView to the view hierarchy. The view will have no size until the ad is loaded.
  aLayout.addView(mAdView);
 }


SBCAdSystem implementation

 To start Madvertise ad network we have to implement start method from SBCAdSystem interface:

 //------------------------------------------------------------------------
 @Override
 public void start()
 {
     mAdView.setVisibility(View.VISIBLE);

     // Start loading the ad in the background.
     mAdView.setFetchingAdsEnabled(true);
 }

 Calling setFetchingAdsEnabled with true will launch our request for ad. With the result of this reqest we will be notified through MadvertiseViewCallbackListener methods.

 Next we need methods to stop and destroy this ad system in case we are switching to another one.

 //------------------------------------------------------------------------
 @Override
 public void stop()
 {
  if (mAdView != null)
  {
   mAdView.setFetchingAdsEnabled(false);
   mAdView.setVisibility(View.GONE);
  }
 }

 //------------------------------------------------------------------------
 @Override
 public void destroy()
 {
  if (mAdView != null)
  {
   mAdView.removeMadViewCallbackListener();
  }
  mLayout.removeAllViews();
 }

 Finally there is method for setting the events listener and for processing keys. The later will again have no implementation for Madvertise:

 //------------------------------------------------------------------------
 @Override
 public void setEventListener(SBCAdEventListener aListener)
 {
  mListener = aListener;
 }
 
 //------------------------------------------------------------------------
 @Override
 public boolean keyDown(final int aKeyCode, final KeyEvent aEvent)
 {
  return false;
 }


MadvertiseViewCallbackListener implementation

 Now comes the implementation of the interface that is part of Madvertise SDK. Again it is very simple as most of the methods will just notify our listener (that means our ad manager that is implementing it) and the rest is more or less just some debug output to watch in LogCat if everything is going well.

 //------------------------------------------------------------------------
 // MadvertiseViewCallbackListener
 //------------------------------------------------------------------------
 @Override
 public void onLoaded(boolean succeed, MadvertiseView madView)
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onLoaded");
  
  if (!succeed)
  {
   mListener.onFailed(this);
  }
 }
 
 //------------------------------------------------------------------------
 @Override
 public void onError(Exception exception)
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onError");
  
  mListener.onFailed(this);
 }

 //------------------------------------------------------------------------
 @Override
 public void onIllegalHttpStatusCode(int statusCode, String message)
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onIllegalHttpStatusCode");
 }

 //------------------------------------------------------------------------
 @Override
 public void onAdClicked()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onAdClicked");
 }

 //------------------------------------------------------------------------
 @Override
 public void onApplicationPause()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onApplicationPause");
 }

 //------------------------------------------------------------------------
 @Override
 public void onApplicationResume()
 {
  Log.d("AdsSystem", SYSTEM_NAME + "onApplicationResume");
 }


Conclusion

  Today we added next ad network to our ad manager system. Next time we will ad Leadbolt network. You can now adjust the constants in SBCAdsConstants.java file so it handles two networks and with probability settings you can say how many percent of your users will ask for AdMob or Madvertise ad.