MAX Advertising Systems Android SDK
MAX is a simple parallel bidding mechanism, which works by running an auction before you call your primary ad waterfall. This "pre-bid" phase allows more than one exchange or programmatic buyer to establish a price for your inventory and then compete at various points in your waterfall.
It works as follows:
- Your app calls MAX to prepare and send a pre-bid request to the MAX backend.
- MAX contacts all of your configured ad sources and collects bids from each.
- The bids are compared and the highest bid that is compliant with your targeting and other rules is selected.
- MAX returns the pre-bid results and a set of keywords.
- Your app calls your ad server/SSP normally, attaching the keywords that were returned. The keywords are designed to match specific line items in your waterfall, which can be set up to trigger only if a certain price is met.
- If a line item matches the keywords, the ad server/SSP hands off to the MAX custom event. The custom event then shows the ad returned in the pre-bid from the partner exchange or buyer.
- If nothing matches a MAX line item, then your waterfall proceeds normally.
In this way, you can increase competition and take control of the exchange layer in your ad waterfall without disrupting the way your ads are served currently.
Using the MAX Android SDK open source Github repository
- Clone the repository locally
git clone [email protected]:MAXAds/max-android-sdk.git
- Open your app in Android Studio and import the code as a module. File > New > Import Module
- Select the sdk directory inside the directory where the repository was cloned: max-android-sdk/sdk
- In your app's build.gradle file add the sdk module as a dependency
compile project(':sdk')
The SDK must be initialized in your Application class before being able to request ads. Example:
public class MyApplication extends Application {
public void onCreate() {
super.onCreate();
MaxAds.initialize(this);
}
}
It is simple to wrap your existing banner ad view with MAX using the MAX RequestManager. MAX will handle all auto-refresh and error retry logic, so you should disable these features on your SSP. Example integration with MoPub:
mRequestManager = new RequestManager();
mRequestManager.setAdUnitId(MAX_BANNER_ADUNIT_ID);
mRequestManager.setRequestListener(new RequestManager.RequestListener() {
@Override
public void onRequestSuccess(@NonNull Ad ad) {
mAd = ad;
mMoPubView.setAdUnitId(MOPUB_BANNER_ADUNIT_ID);
mMoPubView.setKeywords(ad.getPrebidKeywords());
mMoPubView.loadAd();
}
@Override
public void onRequestFail(@NonNull Throwable throwable) {
mRequestManager.startRefreshTimer(RequestManager.DEFAULT_REFRESH_TIME_SECONDS);
}
});
mMoPubView.setBannerAdListener(new MoPubView.BannerAdListener() {
@Override
public void onBannerLoaded(MoPubView banner) {
mRequestManager.startRefreshTimer(mAd.getRefreshTimeSeconds());
}
@Override
public void onBannerFailed(MoPubView banner, MoPubErrorCode errorCode) {
mRequestManager.startRefreshTimer(mAd.getRefreshTimeSeconds());
}
@Override
public void onBannerClicked(MoPubView banner) {
}
@Override
public void onBannerExpanded(MoPubView banner) {
}
@Override
public void onBannerCollapsed(MoPubView banner) {
}
});
mRequestManager.requestAd();
When the Activity or Fragment containing the above code is destroyed, the RequestManager must also be destroyed.
mRequestManager.destroy();
Interstitials work similarly to the above. None of your other interstitial display logic needs to change. Example integration with MoPub:
mRequestManager = new RequestManager();
mRequestManager.setAdUnitId(MAX_INTERSTITIAL_ADUNIT_ID);
mRequestManager.setRequestListener(new RequestManager.RequestListener() {
@Override
public void onRequestSuccess(@NonNull Ad ad) {
mAd = ad;
mMoPubInterstitial.setKeywords(ad.getPrebidKeywords());
mMoPubInterstitial.load();
}
@Override
public void onRequestFail(@NonNull Throwable throwable) {
}
});
mMoPubInterstitial.setInterstitialAdListener(new MoPubInterstitial.InterstitialAdListener() {
@Override
public void onInterstitialLoaded(MoPubInterstitial interstitial) {
mMoPubInterstitial.show();
}
@Override
public void onInterstitialFailed(MoPubInterstitial interstitial, MoPubErrorCode errorCode) {
}
@Override
public void onInterstitialShown(MoPubInterstitial interstitial) {
}
@Override
public void onInterstitialClicked(MoPubInterstitial interstitial) {
}
@Override
public void onInterstitialDismissed(MoPubInterstitial interstitial) {
}
});
mRequestManager.requestAd();
When the Activity or Fragment containing the above code is destroyed, the RequestManager must also be destroyed.
mRequestManager.destroy();
MAX works by triggering line items in your SSP/ad server waterfall using keyword targeting. The keywords returned from the MAX pre-bid system for a $0.26 bid look like this:
m_max:true,max_bidX:000,max_bidXX:020,max_bidXXX:026
This structure allows you to set price increments in your SSP at the dollar, ten cent or single cent level.
To create a MAX line item:
- Create a new line item of type Custom Native Network
- Set the Custom Event Class to the appropriate value depending on their type:
com.mopub.mobileads.MaxMoPubBannerCustomEvent
orcom.mopub.mobileads.MAXMoPubInterstitialCustomEvent
. - Set the Custom Event Info to
{"adunit_id": "<MAX_ADUNIT_ID>"}
where the value ofMAX_ADUNIT_ID
corresponds to the ID of the MAX ad unit for this request.
Use Chrome Developer Tools (chrome://inspect) to view network requests, debug view heirarchies, debug web views
- Stetho - Sophisticated debug bridge for Android applications accessed using Chrome Developer Tools
Configuration:
In your app's build.gradle
compile 'com.facebook.stetho:stetho:1.5.0'
compile 'com.facebook.stetho:stetho-okhttp3:1.5.0'
In your app's Application file
MaxAds.initialize(this,
Collections.<Interceptor>emptyList(),
Collections.<Interceptor>singletonList(new StethoInterceptor()));
- OkHttp3 Logging Interceptor - logs HTTP request and response data to Android Studio Logcat
Configuration:
In your app's build.gradle
compile 'com.squareup.okhttp3:logging-interceptor:3.8.1'
In your app's Application file
MaxAds.initialize(this,
Collections.<Interceptor>singletonList(new HttpLoggingInterceptor().setLevel(level)),
Collections.<Interceptor>emptyList());
- MRAID Log Level
MRAIDLog.setLoggingLevel(logLevel);
- VAST Log Level
VASTLog.setLoggingLevel(logLevel);
- Enable strict mode. SDK will force crash when supplied with invalid arguments to certain methods.
Checks.NoThrow.setStrictMode(true);
- Genymotion - Android emulation platform
Android
- Android Support V4 - Backwards compatibility library for new Android features
- Android Support Annotations - Provide hints to code inspection tools to catch issues before run time
RxJava
Network
- Retrofit - A type-safe HTTP client for Android and Java
- OkHttp - An HTTP & HTTP/2 client for Android and Java applications
- GSON - A Java serialization/deserialization library to convert Java Objects into JSON and back
Testing
- Robolectric - Run unit tests quickly in the JVM instead of an emulator / device
- Mockito - Mocking framework
MAX, [email protected]
MAX is available under the MIT license. See the LICENSE file for more info.