How to add custom network to Admob mediation

[EDIT]:
Scroll down this thread to the approved and correct version of the Geystripe CustomEvent [EDIT]

I want to add a custom network (Greystripe) to my Admob mediation network.

I understand the following:
[ol]
[li]I need to add the network in the Admob dahsboard by supplying the fully qualified class name of my CustomEvent class, a label and optional a String parameter
[/li][li]The optional paramater is passed to my Custom Event class as serverParameter
[/li][li]I need to create a CustomEvent class, which is instantiated by Admob when a request is received.
[/li][/ol]
I found an example of such a CustomEvent class on stackoverflow.com http://stackoverflow.com/questions/11667285/custom-events-in-admob-mediattion-adding-unsupported-ad-networks

This is the class:

public class CustomEvent implements CustomEventBanner, AdListener{

	private CustomEventBannerListener bannerListener;
	private AdView adView;
	private static final String TAG = "CustomEvent";

	@Override
	// interface CustomEventBanner
	public void requestBannerAd(final CustomEventBannerListener listener,
        final Activity activity,
        String label,
        String serverParameter,
        AdSize adSize,
        MediationAdRequest mediationAdRequest) {
	    Log.d(TAG, "requestBannerAd(); serverParameter: " + serverParameter);
		
	    // Keep the custom event listener for use later.
	    this.bannerListener = listener;
	
	    // Determine the best ad format to use given the adSize. If the adSize
	    // isn't appropriate for any format, an ad will not fill.
	    AdSize bestAdSize = adSize = adSize.findBestSize(
	            AdSize.BANNER,
	            AdSize.IAB_BANNER,
	            AdSize.IAB_LEADERBOARD,
	            AdSize.IAB_MRECT,
	            AdSize.IAB_WIDE_SKYSCRAPER);
	    if (bestAdSize == null) {
	        listener.onFailedToReceiveAd();
	        return;
	    }

	    // Initialize an AdView with the bestAdSize and the publisher ID.
	    // The publisher ID is the server parameter that you gave when creating
	    // the custom event.
	    this.adView = new AdView(activity, bestAdSize, serverParameter);
	
	    // Set the listener to register for events.
	    this.adView.setAdListener(this);
	    // Generate an ad request using custom targeting values provided in the
	    // MediationAdRequest.
	    AdRequest adRequest = new AdRequest()
	    .setBirthday(mediationAdRequest.getBirthday())
	    .setGender(mediationAdRequest.getGender())
	    .setKeywords(mediationAdRequest.getKeywords())
	    .setLocation(mediationAdRequest.getLocation());
	    if (mediationAdRequest.isTesting()) {
	        adRequest.addTestDevice(AdRequest.TEST_EMULATOR);
	    }
	
	    // Load the ad with the ad request.
	    this.adView.loadAd(adRequest);
	}

	@Override
	// interface AdListener
	public void onReceiveAd(Ad ad) {
	    Log.d(TAG, "onReceiveAd()");
	    this.bannerListener.onReceivedAd(this.adView);
	}
	
	@Override
	// interface AdListener
	public void onFailedToReceiveAd(Ad ad, ErrorCode errorCode) {
	    Log.d(TAG, "onFailedToReceiveAd(); Errorcode: " + errorCode.toString());
	    this.bannerListener.onFailedToReceiveAd();
	}
	
	@Override
	// interface AdListener
	public void onPresentScreen(Ad ad) {
	    Log.d(TAG, "onPresentScreen()");
	    this.bannerListener.onClick();
	    this.bannerListener.onPresentScreen();
	}
	
	@Override
	// interface AdListener
	public void onDismissScreen(Ad ad) {
	    Log.d(TAG, "onDismissScreen()");
	    this.bannerListener.onDismissScreen();
	}
	
	@Override
	// interface AdListener
	public void onLeaveApplication(Ad ad) {
	    Log.d(TAG, "onLeaveApplication()");
	    this.bannerListener.onLeaveApplication();
	}
}

I believe, I have to modify the method requestBannerAd().
But I dont understand, how I can obtain a reference to my ad container (A LinearLayout tag in my activities’ xml).
Then I check if I receive the ad inside the requestBannerAd() method, add the ad, and call onReceiveAd() .
If I don’t receive one, I call onFailedToReceiveAd() respectively. :huh:

Can anybody enlight me and point me in the right direction?

That code example is actually a little confusing. Here’s a slightly modified version, which I think suits your needs better:

[java]
public class CustomEvent implements CustomEventBanner, AdListener{

private CustomEventBannerListener bannerListener;
private static final String TAG = "CustomEvent";

@Override
// interface CustomEventBanner
public void requestBannerAd(final CustomEventBannerListener listener,
    final Activity activity,
    String label,
    String serverParameter,
    AdSize adSize,
    MediationAdRequest mediationAdRequest) {
    Log.d(TAG, "requestBannerAd(); serverParameter: " + serverParameter);
	
    // Keep the custom event listener for use later.
    this.bannerListener = listener;

    // Get a reference to your ad layout -- PSEUDOCODE
    GreyStripAdView ad = activity.findViewById(R.id.greystripe_ad_layout);

    // Load the ad request -- PSEUDOCODE
    if(ad.loadAd() == Result.SUCCESS) {
        // Tell the AdMob listener that an ad was loaded
        listener.onReceivedAd();
    } else {
        // Tell the AdMob listener that ad failed to load
        listener.onFailedToReceiveAd();
    }
}

}
[/java]

As you can see, the original example was designed to use AdMob mediation to display… a regular AdMob ad. That in itself was confusing. I’ve changed it to include some pseudocode which illustrates how you might integrate Greystripe instead. Basically you should follow these steps:
[ul]
[li]Use activity.findViewById() to get a reference to the ad layout you’re using for Greystripe[/li][li]Tell Greystripe to load a new ad[/li][li]Check whether the Greystripe ad loaded succcessfully. Tell AdMob yes or no.[/li][/ul]
I’ve used pseudocode here, since I don’t know how the Greystripe SDK actually works. But most likely you won’t be able to use the if/then statement I’ve included in this example. You’ll have to set an event listener on the Greystripe ad, which will call a particular function when the ad loads or fails to load. The Greystripe documentation should tell you how to do this.

The way AdMob mediation itself works:
[ul]
[li]Receives an Ad Request[/li][li]Calls the requestBannerAd() function on your Custom Class[/li][li]Waits for your Custom Class to call listener.onReceivedAd() or listener.onFailedToReceiveAd()[/li][li]If failed, AdMob continues to next network in your mediation settings[/li][li]If succeeded, AdMob stops trying networks.[/li][/ul]
Hope that helps! I’ve only ever used AdMob mediation for interstitials, so this code for banners is untested. But it follows most of the same principles, and should work fine for your implementation.

That example IS confusing, for the reason you noted. Figured that out too by now. Explaining CustomEvents in Admob by using Admob ads as unsupported network is kinda skewed. :smiley:
Thanks for your help.

Finally, here a working implementation of Greystripe CustomEvent class.
This is the minimum of methods, which need to be implemented.

From that, I went to implement a few other CustomEvent classes for other unsupported network (Mobclix, Madvertise). Mobclix is pretty similiar. Madvertise requires some extra code. and an Interface. If there is interest, I can open a new thread for Madvertise CustomEvent class.

There is a more detailled thread of the Greystripe CustomEvent class here

public class GreystripeCustomEvent implements CustomEventBanner, GSAdListener {

	private CustomEventBannerListener bannerListener;
	private GSMobileBannerAdView adView;
	
        private Activity activity;
        private static final String TAG = "GreystripeCustomEvent";

        // interface CustomEventBanner
	@Override
	public void requestBannerAd(CustomEventBannerListener listener, 
			Activity activity,
			String label, 
			String serverParameter, 
			AdSize adSize, 
			MediationAdRequest mediationAdRequest) {
		// TODO Auto-generated method stub
		Log.d(TAG, "requestBannerAd()");
		
		// Keep the custom event listener for use later.
		this.bannerListener = listener;
		this.activity = activity;
		Log.d(TAG, "requestBannerAd() after this.activity = activity");
		Log.d(TAG, "activity: " + activity.toString());
		
		// Initialize an AdView with the publisher ID.
		// The publisher ID is the server parameter that you gave when creating
		// the custom event.
		adView = new GSMobileBannerAdView(activity, serverParameter);
        adView.addListener(this);
        adView.refresh();
		Log.d(TAG, "requestBannerAd() after adview.refresh()");
	}
	
	// interface GSAdListener
	@Override
	public void onAdClickthrough(GSAd arg0) {
		// TODO Auto-generated method stub

	}

	// interface GSAdListener
	@Override
	public void onAdDismissal(GSAd arg0) {
		// TODO Auto-generated method stub

	}

	// interface GSAdListener
	@Override
	public void onFailedToFetchAd(GSAd gsad, GSAdErrorCode error) {
		// TODO Auto-generated method stub
		 this.bannerListener.onFailedToReceiveAd();

	}

	// interface GSAdListener
	@Override
	public void onFetchedAd(GSAd gsad) {
		// TODO Auto-generated method stub
		Log.d(TAG, "onFetchedAd()");
		Log.d(TAG, "activity: " + activity.toString());

		LinearLayout adContainer = (LinearLayout) activity.findViewById(R.id.ad_container);
		adContainer.removeAllViews();
		adContainer.setPadding(0, 0, 0, 0);
		Log.d(TAG, "onFetchedAd(): after findViewById");
		Log.d(TAG, "adContainer: " + adContainer.toString());
		adContainer.addView(adView);
		
		Log.d(TAG, "onFetchedAd(): after addView");
		ImageView img = new ImageView(activity);
		this.bannerListener.onReceivedAd(img);

	}
}

Happy coding!:D

What extra code did you need for Madvertise? I also integrated it and did it pretty similar to your Greystripe implementation. Did I miss something obvious? :slight_smile:

How is Greystipe performing btw?

Madvertise use the mtracker to pause and resume tracking with the activities lifecycle events. I dont know if it is necessary to follow them, too, but I guess one should.
Basically you let the CustomEvent class listen to activity life cycle events and forward these events to the respective methods as they are used in Madvertise demo app. You can do this elegantly by writing a listener class, add the listener to the activity in the CustomEvents onCreate(). To make sure, you dont forget it add these code in all activities using Greystripe, make an inteface, so that your app won’t compile, if you forget.

No statistics from Greystripe yet, because I haven’t updated my app in the market yet. My app is relatively large, so I usually only push out releases, once a couple of changes are accumulated. In my case, that would be adding a set of ad networks, so I can switch them off and on in Admob dashboard as I please.
Greystripe claims to be more focussed on the european and german market, that’s why I try them.

Unfortunately there was still a bug in my GreystripeCustomEvent class. Here is the corrected, by Eric from Google Groups Ad Developer (Eric works for Google) reviewed class:

public class GreystripeCustomEvent implements CustomEventBanner, GSAdListener {

	private CustomEventBannerListener bannerListener;
	private GSMobileBannerAdView adView;
    private Activity activity;
    private static final String TAG = "GreystripeCustomEvent";

    // interface CustomEventBanner
	@Override
	public void requestBannerAd(CustomEventBannerListener listener, 
			Activity activity,
			String label, 
			String serverParameter, 
			AdSize adSize, 
			MediationAdRequest mediationAdRequest) {
		// TODO Auto-generated method stub
		Log.d(TAG, "requestBannerAd()");
		
		// Keep the custom event listener for use later.
		this.bannerListener = listener;
		this.activity = activity;
		Log.d(TAG, "requestBannerAd() after this.activity = activity");
		Log.d(TAG, "activity: " + activity.toString());
		
		// Initialize an AdView with the publisher ID.
		// The publisher ID is the server parameter that we when creating
		// the custom event in the admob dashboard
		adView = new GSMobileBannerAdView(activity, serverParameter);
        adView.addListener(this);
        adView.refresh();
		Log.d(TAG, "requestBannerAd() after adview.refresh()");
	}
	
	// interface GSAdListener
	@Override
	public void onAdClickthrough(GSAd arg0) {
		// TODO Auto-generated method stub

	}

	// interface GSAdListener
	@Override
	public void onAdDismissal(GSAd arg0) {
		// TODO Auto-generated method stub

	}

	// interface GSAdListener
	@Override
	public void onFailedToFetchAd(GSAd gsad, GSAdErrorCode error) {
		// TODO Auto-generated method stub
		this.bannerListener.onFailedToReceiveAd();

	}

	// interface GSAdListener
	@Override
	public void onFetchedAd(GSAd gsad) {
		// TODO Auto-generated method stub
		Log.d(TAG, "onFetchedAd()");
		
		// we need to add LayoutParams, otherwise the ad skews the layout
		Resources r = activity.getResources();
		int pixWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 320, r.getDisplayMetrics());
		int pixHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, r.getDisplayMetrics());
		LinearLayout.LayoutParams params  = new LinearLayout.LayoutParams(pixWidth, pixHeight);
		adView.setLayoutParams(params);
		this.bannerListener.onReceivedAd(adView);
		Log.d(TAG, "onFetchedAd(): after bannerListener.onReceivedAd(adView)");

	}
}

Eric said, one should be careful about not leaking the activity. As far as I can tell from my LogCat, it doesn’t leak.

Adding madvertise and greystripe to admob mediation …

From the solutions given it seems one needs to first be doing things programmatically (probably the best way eventually - as it may allow better control of ad fetch - thus allowing non-display of ad if user is not looking at screen or idle).

However at the moment I wanted a solution that would work with the XML way of integrating admob mediation.

I got the madvertise SDK - and madvertise provided some code for mediation also (which they say has worked for others).

However they don’t provide the madvertise SDK as a library. But as a project - and a project that my eclipse on windows is unable to recognize.

Their samples are also unrecognizable in eclipse on windows.

Perhaps there is a way to do all this - but it is going to take more than the “hour” which many (other) ad networks say it takes to get their SDK integrated with admob mediation.

Anyone have any pointers to how to get madvertise integrated - will have to use two views - hide one etc. all that ?

Is the same type of programmatic stuff going to be required for greystrike ?

I just added greystripe banner ads to admob mediation using the code provided by “mradlmaier” above.

And it is working ok (I am testing with greystripe testing banner ads using the publisher ID that the greystripe SDKDemo app was using - I will switch to using my own app’s greystripe publisher ID if I ever decide to use greystripe banner ads).

Here is a step-by-step guide for integrating greystripe banner ads in admob mediation.

In eclipse - create a new class (i.e. java file). Right-click on a directory where you want to store it.

For example if your app package name is:

com.yourdomain.YourApp

In eclipse you will have:


YourApp/
    src/
        com.yourdomain.YourApp/
            YourActivity.java
            ....
        com.yourdomain.Utility/

Suppose you want to add it to com.yourdomain.Utility (which may be where you store code that you will reuse and not specifically related to the app).

right-click on com.yourdomain.Utility - New - Class

enter the Class name: GreystripeCustomEvent

It will show the GreystripeCustomEvent.java file.

Now just replace the lines:


public class GreystripeCustomEvent {
}

With the code in the the post above by mradlmaier.

You will see warning (red) errors.

This is because you are missing the import lines.

In eclipse - press ctrl-shift-o - this will give a suggestion box - select:

android.Util.Log

You will see that eclipse will have filled in the “import” lines at the top of the file.

The new lines are something like:


import android.app.Activity;
import android.content.res.Resources;
import android.util.Log;
import android.util.TypedValue;
import android.widget.LinearLayout;

import com.google.ads.AdSize;
import com.google.ads.mediation.MediationAdRequest;
import com.google.ads.mediation.customevent.CustomEventBanner;
import com.google.ads.mediation.customevent.CustomEventBannerListener;
import com.greystripe.sdk.GSAd;
import com.greystripe.sdk.GSAdErrorCode;
import com.greystripe.sdk.GSAdListener;
import com.greystripe.sdk.GSMobileBannerAdView;

You can see that the android.util.Log refers to the calls to Log.d() (to output debug messages to logcat).

And that the google admob SDK AND the greystripe SDK references have been added automatically eclipse.

This code will now be showing no red warnings. But will compile when you:

Project - Clean
right-click on project - Refresh
right-click on project - Run As - Android Application

If your phone is attached to the USB cable, the app will now run on your phone (or in your emulator if no phone is connected to USB).

And you will be able to see the greystripe ads.

If you want to see the Log.d() output in the logcat (so you know which method was called when by admob mediation), you can change the Log.d to Log.v and these messages will become visible (this is because Log.d() are debug messages and will NOT be visible in logcat with a release build).

If you use Log.v() instead, and run the app on your phone - type “GreystripeCustomEvent” in the search field for logcat and you will see the messages as ads are fetched etc.

Admob mediation settings …

I have skipped a step above - PRIOR to running the app on your phone, you should setup admob mediation settings to include greystripe.

Go to:
https://mediation.admob.com/

Sites & Apps - Ad network mediation

I am assuming you already have set up at least one app for admob mediation - so you will have at least one entry here.

Move mouse close to the app setting - and a “Manage Settings” link will appear - click on that.

Click on the “Add Custom Event” tab - a dialog box will open - enter the settings for greystripe:


Label:		Greystripe CustomEvent banner

(this is the name that Admob will show for this setting)
(it seems this can be any text)

Class name:	com.yourdomain.Utility.GreystripeCustomEvent
Parameter:	xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

The “Parameter” should be your greystripe publisher ID.

HOWEVER, if you just want to test, you can use the publisher ID provided in the greystripe “SDKDemo” app.

That seems to work much better than the “Test device” settings - when I set up a test device etc. so testing ads are delivered those did not appear always - but when I switched to using the SAME publisher ID that the greystripe “SDKDemo” app is using, then it worked well.

In the greystripe SDKDemo app the publisher ID can be found in the AndroidManifest.xml file:


<meta-data android:name="gs_guid" android:value="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"/>

Hope this helps.

[hr]
The question is - is it that easy to integrate madvertise ?

I couldn’t even get the SDK to be recognized on eclipse.

Also was there any problem with madvertise 320x53 banner size (different from 320x50 banner size usually used).
[hr]
Edited the post above to show WHERE the greystripe publisher ID is stored (and where to copy the greystripe SDKDemo publisher ID for testing):

In the greystripe SDKDemo app the publisher ID can be found in the AndroidManifest.xml file:

<meta-data android:name=“gs_guid” android:value=“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”/>

There was a small bug (according to Leichtenschlag from Google) in my implemenentation of the Greystripe CustomEvent class, in the onFetchedAd() method:

Here is the correct and approved code:

public class GreystripeCustomEvent implements CustomEventBanner, GSAdListener {

	private CustomEventBannerListener bannerListener;
	private GSMobileBannerAdView adView;
    private Activity activity;
    private static final String TAG = "GreystripeCustomEvent";

    // interface CustomEventBanner
	@Override
	public void requestBannerAd(CustomEventBannerListener listener, 
			Activity activity,
			String label, 
			String serverParameter, 
			AdSize adSize, 
			MediationAdRequest mediationAdRequest) {
		// TODO Auto-generated method stub
		Log.d(TAG, "requestBannerAd()");
		
		// Keep the custom event listener for use later.
		this.bannerListener = listener;
		this.activity = activity;
		Log.d(TAG, "requestBannerAd() after this.activity = activity");
		Log.d(TAG, "activity: " + activity.toString());
		
		// Initialize an AdView with the publisher ID.
		// The publisher ID is the server parameter that we when creating
		// the custom event in the admob dashboard
		adView = new GSMobileBannerAdView(activity, serverParameter);
        adView.addListener(this);
        adView.refresh();
		Log.d(TAG, "requestBannerAd() after adview.refresh()");
	}
	
	// interface GSAdListener
	@Override
	public void onAdClickthrough(GSAd arg0) {
		// TODO Auto-generated method stub

	}

	// interface GSAdListener
	@Override
	public void onAdDismissal(GSAd arg0) {
		// TODO Auto-generated method stub

	}

	// interface GSAdListener
	@Override
	public void onFailedToFetchAd(GSAd gsad, GSAdErrorCode error) {
		// TODO Auto-generated method stub
		this.bannerListener.onFailedToReceiveAd();

	}

	// interface GSAdListener
	@Override
	public void onFetchedAd(GSAd gsad) {
		// TODO Auto-generated method stub
		Log.d(TAG, "onFetchedAd()");
		
		// we need to add LayoutParams, otherwise the ad skews the layout
		Resources r = activity.getResources();
		int pixWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 320, r.getDisplayMetrics());
		int pixHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, r.getDisplayMetrics());
		LinearLayout.LayoutParams params  = new LinearLayout.LayoutParams(pixWidth, pixHeight);
		adView.setLayoutParams(params);
		this.bannerListener.onReceivedAd(adView);
		Log.d(TAG, "onFetchedAd(): after bannerListener.onReceivedAd(adView)");

	}
}

Much appreciated.

Can you give some feedback on madvertise integration with admob ?

Thanks.

Sorry for the late reply, haven’t found time yet.

In my blog I have posted the complete source code on how to integrate Madvertise into the Admob mediation:

http://www.mradlmaier.com/index.php/de/blog/42-madvertise-integration-in-die-admob-mediation

The post is in german language, but you can simply cut and paste the source code. Once I have time, I will translate the post to english.

Thanks.

English translation is ready and here.

Thanks.