Skip to content

Instantly share code, notes, and snippets.

@thomasmso
Last active May 26, 2020 18:28
Show Gist options
  • Save thomasmso/97130c6e10340dabddd8a59ff5156558 to your computer and use it in GitHub Desktop.
Save thomasmso/97130c6e10340dabddd8a59ff5156558 to your computer and use it in GitHub Desktop.
package com.applovin.mediation.adapters;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import com.applovin.mediation.MaxAdFormat;
import com.applovin.mediation.adapter.MaxAdViewAdapter;
import com.applovin.mediation.adapter.MaxAdapterError;
import com.applovin.mediation.adapter.MaxInterstitialAdapter;
import com.applovin.mediation.adapter.MaxRewardedAdapter;
import com.applovin.mediation.adapter.MaxSignalProvider;
import com.applovin.mediation.adapter.listeners.MaxAdViewAdapterListener;
import com.applovin.mediation.adapter.listeners.MaxInterstitialAdapterListener;
import com.applovin.mediation.adapter.listeners.MaxRewardedAdapterListener;
import com.applovin.mediation.adapter.listeners.MaxSignalCollectionListener;
import com.applovin.mediation.adapter.parameters.MaxAdapterInitializationParameters;
import com.applovin.mediation.adapter.parameters.MaxAdapterResponseParameters;
import com.applovin.mediation.adapter.parameters.MaxAdapterSignalCollectionParameters;
import com.applovin.mediation.adapters.mintegral.BuildConfig;
import com.applovin.sdk.AppLovinSdk;
import com.mintegral.msdk.MIntegralConstans;
import com.mintegral.msdk.MIntegralSDK;
import com.mintegral.msdk.activity.MTGCommonActivity;
import com.mintegral.msdk.interstitialvideo.out.InterstitialVideoListener;
import com.mintegral.msdk.interstitialvideo.out.MTGBidInterstitialVideoHandler;
import com.mintegral.msdk.interstitialvideo.out.MTGInterstitialVideoHandler;
import com.mintegral.msdk.mtgbid.out.BidManager;
import com.mintegral.msdk.out.BannerAdListener;
import com.mintegral.msdk.out.BannerSize;
import com.mintegral.msdk.out.MIntegralSDKFactory;
import com.mintegral.msdk.out.MTGBannerView;
import com.mintegral.msdk.out.MTGBidRewardVideoHandler;
import com.mintegral.msdk.out.MTGConfiguration;
import com.mintegral.msdk.out.MTGRewardVideoHandler;
import com.mintegral.msdk.out.RewardVideoListener;
import com.mintegral.msdk.reward.player.MTGRewardVideoActivity;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class MintegralMediationAdapter
extends MediationAdapterBase
implements MaxInterstitialAdapter, MaxRewardedAdapter, MaxAdViewAdapter, MaxSignalProvider
{
private static final AtomicBoolean INITIALIZED = new AtomicBoolean();
private static final String APP_ID_PARAMETER = "app_id";
private static final String APP_KEY_PARAMETER = "app_key";
// Possible ad load error messages received from Mintegral in an email
private final static String NOT_INITIALIZED = "init error";
private final static String NO_FILL_1 = "no ads available can show";
private final static String NO_FILL_2 = "no ads available";
private final static String NO_FILL_3 = "no server ads available";
private final static String NO_FILL_4 = "no ads source";
private final static String NETWORK_ERROR = "network exception";
private final static String BAD_REQUEST = "request parameter is null";
private final static String TIMEOUT = "load timeout";
private final static String UNIT_ID_EMPTY = "UnitId is null";
private final static String NETWORK_IO_ERROR = "Network error,I/O exception";
// List of Mintegral error codes not defined in API, but in their docs
//
// http://cdn-adn.rayjump.com/cdn-adn/v2/markdown_v2/index.html?file=sdk-m_sdk-android&lang=en#faqs
//
private final static String EXCEPTION_RETURN_EMPTY = "EXCEPTION_RETURN_EMPTY"; // ads no fill
private final static String EXCEPTION_TIMEOUT = "EXCEPTION_TIMEOUT"; // request timeout
private final static String EXCEPTION_IV_RECALLNET_INVALIDATE = "EXCEPTION_IV_RECALLNET_INVALIDATE"; // The network status at the time of the request is incorrect. Generally, because of the SDK initialization is not completed yet when the request has been sent.
private final static String EXCEPTION_SIGN_ERROR = "EXCEPTION_SIGN_ERROR"; // AppID and appKey do not match correctly
private final static String EXCEPTION_UNIT_NOT_FOUND = "EXCEPTION_UNIT_NOT_FOUND"; // Can not find the unitID in dashboard
private final static String EXCEPTION_UNIT_ID_EMPTY = "EXCEPTION_UNIT_ID_EMPTY"; // unitID is empty
private final static String EXCEPTION_UNIT_NOT_FOUND_IN_APP = "EXCEPTION_UNIT_NOT_FOUND_IN_APP"; // Can not find the unitID of the appID
private final static String EXCEPTION_UNIT_ADTYPE_ERROR = "EXCEPTION_UNIT_ADTYPE_ERROR"; // The adtype of the unitID is wrong
private final static String EXCEPTION_APP_ID_EMPTY = "EXCEPTION_APP_ID_EMPTY"; // appID is empty
private final static String EXCEPTION_APP_NOT_FOUND = "EXCEPTION_APP_NOT_FOUND"; // Can not find the appId
private static String sSdkVersion;
// Mintegral suggested we keep a map of unit id -> handler to prevent re-creation / high error rates - https://app.asana.com/0/573104092700345/1166998599374502
private static final Map<String, MTGInterstitialVideoHandler> mtgInterstitialVideoHandlers = new HashMap<>();
private static final Map<String, MTGBidInterstitialVideoHandler> mtgBidInterstitialVideoHandlers = new HashMap<>();
private static final Map<String, MTGRewardVideoHandler> mtgRewardVideoHandlers = new HashMap<>();
private static final Map<String, MTGBidRewardVideoHandler> mtgBidRewardVideoHandlers = new HashMap<>();
// Supports video, interactive, and banner ad formats
private MTGInterstitialVideoHandler mtgInterstitialVideoHandler;
private MTGBidInterstitialVideoHandler mtgBidInterstitialVideoHandler;
private MTGRewardVideoHandler mtgRewardVideoHandler;
private MTGBidRewardVideoHandler mtgBidRewardVideoHandler;
private MTGBannerView mtgBannerView;
// Explicit default constructor declaration
public MintegralMediationAdapter(final AppLovinSdk sdk) { super( sdk ); }
@Override
public void initialize(final MaxAdapterInitializationParameters parameters, final Activity activity, final OnCompletionListener onCompletionListener)
{
// Check existence of SDK classes
checkExistence( MTGInterstitialVideoHandler.class, MTGRewardVideoHandler.class );
// Check existence of SDK activities
checkExistence( MTGCommonActivity.class, MTGRewardVideoActivity.class );
MIntegralConstans.DEBUG = parameters.isTesting();
if ( INITIALIZED.compareAndSet( false, true ) )
{
final String appId = parameters.getServerParameters().getString( APP_ID_PARAMETER );
final String appKey = parameters.getServerParameters().getString( APP_KEY_PARAMETER );
final MIntegralSDK mIntegralSDK = MIntegralSDKFactory.getMIntegralSDK();
// Communicated over email, GDPR status can only be set before SDK initialization
final int consent = parameters.hasUserConsent() ? MIntegralConstans.IS_SWITCH_ON : MIntegralConstans.IS_SWITCH_OFF;
mIntegralSDK.setUserPrivateInfoType( activity, MIntegralConstans.AUTHORITY_ALL_INFO, consent );
mIntegralSDK.setConsentStatus( activity, consent );
// Has to be _before_ their SDK init as well
if ( AppLovinSdk.VERSION_CODE >= 91100 && parameters.isDoNotSell() )
{
mIntegralSDK.setDoNotTrackStatus( parameters.isDoNotSell() );
}
// Mintegral Docs - "It is recommended to use the API in the main thread"
final Map<String, String> map = mIntegralSDK.getMTGConfigurationMap( appId, appKey );
mIntegralSDK.init( map, activity );
}
if ( AppLovinSdk.VERSION_CODE >= 90800 ) // 9.8.0+
{
onCompletionListener.onCompletion( InitializationStatus.DOES_NOT_APPLY, null );
}
else
{
onCompletionListener.onCompletion();
}
}
@Override
public String getSdkVersion()
{
if ( sSdkVersion == null )
{
sSdkVersion = getVersionString( MTGConfiguration.class, "SDK_VERSION" );
}
return sSdkVersion;
}
@Override
public String getAdapterVersion()
{
return BuildConfig.VERSION_NAME;
}
@Override
public void collectSignal(final MaxAdapterSignalCollectionParameters parameters, final Activity activity, final MaxSignalCollectionListener callback)
{
// DOCS: https://app.asana.com/0/20387143076905/1126882455204927
log( "Collecting signal..." );
// "3.2.5 - This step is only required for developers using the server to server bidding architecture"
final String signal = BidManager.getBuyerUid( activity );
callback.onSignalCollected( signal );
}
@Override
public void loadInterstitialAd(final MaxAdapterResponseParameters parameters, final Activity activity, final MaxInterstitialAdapterListener listener)
{
InterstitialVideoListener adListener = new InterstitialVideoListener()
{
@Override
public void onVideoLoadSuccess(final String placementId, final String unitId)
{
// Ad has loaded and video has been downloaded
log( "Interstitial successfully loaded and video has been downloaded" );
listener.onInterstitialAdLoaded();
}
@Override
public void onLoadSuccess(final String placementId, final String unitId)
{
// Ad has loaded but video still needs to be downloaded
log( "Interstitial successfully loaded but video still needs to be downloaded" );
}
@Override
public void onVideoLoadFail(final String errorMsg)
{
log( "Interstitial failed to load: " + errorMsg );
listener.onInterstitialAdLoadFailed( toMaxError( errorMsg ) );
}
@Override
public void onAdShow()
{
log( "Interstitial displayed" );
listener.onInterstitialAdDisplayed();
}
@Override
public void onShowFail(final String errorMsg)
{
log( "Interstitial failed to show: " + errorMsg );
listener.onInterstitialAdDisplayFailed( toMaxError( errorMsg ) );
}
@Override
public void onVideoAdClicked(final String placementId, final String unitId)
{
log( "Interstitial clicked" );
listener.onInterstitialAdClicked();
}
@Override
public void onAdClose(final boolean isCompleteView)
{
log( "Interstitial hidden" );
listener.onInterstitialAdHidden();
}
@Override
public void onVideoComplete(final String placementId, final String unitId)
{
log( "Interstitial video completed" );
}
@Override
public void onAdCloseWithIVReward(final boolean isComplete, final int rewardAlertStatus)
{
// This is the ad close callback for when the interstitial has a reward.
}
@Override
public void onEndcardShow(final String placementId, final String unitId)
{
log( "Interstitial endcard shown" );
}
};
final boolean shouldUpdateMuteState = parameters.getServerParameters().containsKey( "is_muted" ); // Introduced in 9.10.0
final int muteState = parameters.getServerParameters().getBoolean( "is_muted" ) ? MIntegralConstans.REWARD_VIDEO_PLAY_MUTE : MIntegralConstans.INTER_ACTIVE_VIDEO_PLAY_NOT_MUTE;
final String unitId = parameters.getThirdPartyAdPlacementId();
if ( !TextUtils.isEmpty( parameters.getBidResponse() ) )
{
log( "Loading bidding interstitial ad for unit id: " + unitId + "..." );
if ( mtgBidInterstitialVideoHandlers.containsKey( unitId ) )
{
mtgBidInterstitialVideoHandler = mtgBidInterstitialVideoHandlers.get( unitId );
}
else
{
mtgBidInterstitialVideoHandler = new MTGBidInterstitialVideoHandler( activity, null, unitId );
mtgBidInterstitialVideoHandlers.put( unitId, mtgBidInterstitialVideoHandler );
}
mtgBidInterstitialVideoHandler.setInterstitialVideoListener( adListener );
if ( mtgBidInterstitialVideoHandler.isBidReady() )
{
log( "A bidding interstitial ad is ready already" );
listener.onInterstitialAdLoaded();
}
else
{
// Update mute state if configured by backend
if ( shouldUpdateMuteState ) mtgBidInterstitialVideoHandler.playVideoMute( muteState );
mtgBidInterstitialVideoHandler.loadFromBid( parameters.getBidResponse() );
}
}
else
{
log( "Loading mediated interstitial ad for unit id: " + unitId + "..." );
if ( mtgInterstitialVideoHandlers.containsKey( unitId ) )
{
mtgInterstitialVideoHandler = mtgInterstitialVideoHandlers.get( unitId );
}
else
{
mtgInterstitialVideoHandler = new MTGInterstitialVideoHandler( activity, null, unitId );
mtgInterstitialVideoHandlers.put( unitId, mtgInterstitialVideoHandler );
}
mtgInterstitialVideoHandler.setInterstitialVideoListener( adListener );
if ( mtgInterstitialVideoHandler.isReady() )
{
log( "A mediated interstitial ad is ready already" );
listener.onInterstitialAdLoaded();
}
else
{
// Update mute state if configured by backend
if ( shouldUpdateMuteState ) mtgInterstitialVideoHandler.playVideoMute( muteState );
mtgInterstitialVideoHandler.load();
}
}
}
@Override
public void showInterstitialAd(final MaxAdapterResponseParameters parameters, final Activity activity, final MaxInterstitialAdapterListener listener)
{
if ( mtgBidInterstitialVideoHandler != null && mtgBidInterstitialVideoHandler.isBidReady() )
{
log( "Showing bidding interstitial..." );
mtgBidInterstitialVideoHandler.showFromBid();
}
else if ( mtgInterstitialVideoHandler != null && mtgInterstitialVideoHandler.isReady() )
{
log( "Showing mediated interstitial..." );
mtgInterstitialVideoHandler.show();
}
else
{
log( "Unable to show interstitial - no ad loaded..." );
// Ad load failed
listener.onInterstitialAdDisplayFailed( MaxAdapterError.AD_NOT_READY );
}
}
@Override
public void loadRewardedAd(final MaxAdapterResponseParameters parameters, final Activity activity, final MaxRewardedAdapterListener listener)
{
RewardVideoListener adListener = new RewardVideoListener()
{
@Override
public void onVideoLoadSuccess(final String placementId, final String unitId)
{
// Ad has loaded and video has been downloaded
log( "Rewarded ad successfully loaded and video has been downloaded" );
listener.onRewardedAdLoaded();
}
@Override
public void onLoadSuccess(final String placementId, final String unitId)
{
// Ad has loaded but video still needs to be downloaded
log( "Rewarded ad successfully loaded but video still needs to be downloaded" );
}
@Override
public void onVideoLoadFail(final String errorMsg)
{
log( "Rewarded ad failed to load: " + errorMsg );
listener.onRewardedAdLoadFailed( toMaxError( errorMsg ) );
}
@Override
public void onAdShow()
{
log( "Rewarded ad displayed" );
listener.onRewardedAdDisplayed();
listener.onRewardedAdVideoStarted();
}
@Override
public void onShowFail(final String errorMsg)
{
log( "Rewarded ad failed to show: " + errorMsg );
listener.onRewardedAdDisplayFailed( toMaxError( errorMsg ) );
}
@Override
public void onVideoAdClicked(final String placementId, final String unitId)
{
log( "Rewarded ad clicked" );
listener.onRewardedAdClicked();
}
@Override
public void onAdClose(final boolean isCompleteView, final String rewardName, final float rewardAmount)
{
log( "Rewarded ad hidden" );
if ( isCompleteView )
{
listener.onRewardedAdVideoCompleted();
listener.onUserRewarded( getReward() );
}
else if ( shouldAlwaysRewardUser() )
{
listener.onUserRewarded( getReward() );
}
listener.onRewardedAdHidden();
}
@Override
public void onVideoComplete(final String placementId, final String unitId)
{
log( "Rewarded ad video completed" );
}
@Override
public void onEndcardShow(final String placementId, final String unitId)
{
log( "Rewarded ad endcard shown" );
}
};
final boolean shouldUpdateMuteState = parameters.getServerParameters().containsKey( "is_muted" ); // Introduced in 9.10.0
final int muteState = parameters.getServerParameters().getBoolean( "is_muted" ) ? MIntegralConstans.REWARD_VIDEO_PLAY_MUTE : MIntegralConstans.INTER_ACTIVE_VIDEO_PLAY_NOT_MUTE;
final String unitId = parameters.getThirdPartyAdPlacementId();
if ( !TextUtils.isEmpty( parameters.getBidResponse() ) )
{
log( "Loading bidding rewarded ad for unit id: " + unitId + "..." );
if ( mtgBidRewardVideoHandlers.containsKey( unitId ) )
{
mtgBidRewardVideoHandler = mtgBidRewardVideoHandlers.get( unitId );
}
else
{
mtgBidRewardVideoHandler = new MTGBidRewardVideoHandler( activity, null, unitId );
mtgBidRewardVideoHandlers.put( unitId, mtgBidRewardVideoHandler );
}
mtgBidRewardVideoHandler.setRewardVideoListener( adListener );
if ( mtgBidRewardVideoHandler.isBidReady() )
{
log( "A bidding rewarded ad is ready already" );
listener.onRewardedAdLoaded();
}
else
{
// Update mute state if configured by backend
if ( shouldUpdateMuteState ) mtgBidRewardVideoHandler.playVideoMute( muteState );
mtgBidRewardVideoHandler.loadFromBid( parameters.getBidResponse() );
}
}
else
{
log( "Loading mediated rewarded ad for unit id: " + unitId + "..." );
if ( mtgRewardVideoHandlers.containsKey( unitId ) )
{
mtgRewardVideoHandler = mtgRewardVideoHandlers.get( unitId );
}
else
{
mtgRewardVideoHandler = new MTGRewardVideoHandler( activity, null, unitId );
mtgRewardVideoHandlers.put( unitId, mtgRewardVideoHandler );
}
mtgRewardVideoHandler.setRewardVideoListener( adListener );
if ( mtgRewardVideoHandler.isReady() )
{
log( "A mediated rewarded ad is ready already" );
listener.onRewardedAdLoaded();
}
else
{
// Update mute state if configured by backend
if ( shouldUpdateMuteState ) mtgRewardVideoHandler.playVideoMute( muteState );
mtgRewardVideoHandler.load();
}
}
}
@Override
public void showRewardedAd(final MaxAdapterResponseParameters parameters, final Activity activity, final MaxRewardedAdapterListener listener)
{
// Configure userReward from server.
configureReward( parameters );
final Bundle serverParameters = parameters.getServerParameters();
final String rewardId = serverParameters.getString( "reward_id", "" );
final String userId = serverParameters.getString( "user_id", "" );
if ( mtgBidRewardVideoHandler != null && mtgBidRewardVideoHandler.isBidReady() )
{
log( "Showing bidding rewarded ad..." );
mtgBidRewardVideoHandler.showFromBid( rewardId, userId );
}
else if ( mtgRewardVideoHandler != null && mtgRewardVideoHandler.isReady() )
{
log( "Showing mediated rewarded ad..." );
mtgRewardVideoHandler.show( rewardId, userId );
}
else
{
log( "Unable to show rewarded ad - no ad loaded..." );
// Ad load failed
listener.onRewardedAdDisplayFailed( MaxAdapterError.AD_NOT_READY );
}
}
@Override
public void loadAdViewAd(final MaxAdapterResponseParameters parameters, final MaxAdFormat adFormat, final Activity activity, final MaxAdViewAdapterListener listener)
{
BannerSize size = toBannerSize( adFormat );
mtgBannerView = new MTGBannerView( activity );
mtgBannerView.init( size, null, parameters.getThirdPartyAdPlacementId() );
mtgBannerView.setAllowShowCloseBtn( false );
mtgBannerView.setRefreshTime( 0 );
mtgBannerView.setBannerAdListener( new BannerAdListener()
{
@Override
public void onLoadSuccessed()
{
log( "Banner ad loaded" );
listener.onAdViewAdLoaded( mtgBannerView );
}
@Override
public void onLoadFailed(final String msg)
{
log( "Banner ad failed to load: " + msg );
listener.onAdViewAdLoadFailed( toMaxError( msg ) );
}
@Override
public void onLogImpression()
{
log( "Banner ad displayed" );
listener.onAdViewAdDisplayed();
}
@Override
public void onClick()
{
log( "Banner ad clicked" );
listener.onAdViewAdClicked();
}
@Override
public void onLeaveApp()
{
log( "Banner ad will leave application" );
}
@Override
public void showFullScreen()
{
log( "Banner ad expanded" );
listener.onAdViewAdExpanded();
}
@Override
public void closeFullScreen()
{
log( "Banner ad collapsed" );
listener.onAdViewAdCollapsed();
}
@Override
public void onCloseBanner()
{
log( "Banner ad closed" );
}
} );
if ( !TextUtils.isEmpty( parameters.getBidResponse() ) )
{
log( "Loading bidding banner ad..." );
mtgBannerView.loadFromBid( parameters.getBidResponse() );
}
else
{
log( "Loading mediated banner ad..." );
mtgBannerView.load();
}
}
@Override
public void onDestroy()
{
if ( mtgInterstitialVideoHandler != null )
{
mtgInterstitialVideoHandler.setInterstitialVideoListener( null );
mtgInterstitialVideoHandler = null;
}
if ( mtgBidInterstitialVideoHandler != null )
{
mtgBidInterstitialVideoHandler.setInterstitialVideoListener( null );
mtgBidInterstitialVideoHandler = null;
}
if ( mtgRewardVideoHandler != null )
{
mtgRewardVideoHandler.setRewardVideoListener( null );
mtgRewardVideoHandler = null;
}
if ( mtgBidRewardVideoHandler != null )
{
mtgBidRewardVideoHandler.setRewardVideoListener( null );
mtgBidRewardVideoHandler = null;
}
if ( mtgBannerView != null )
{
mtgBannerView.release();
mtgBannerView = null;
}
}
private MaxAdapterError toMaxError(final String errorMsg)
{
// Note: we are using `contains()` in some cases b/c Mintegral prepends the message with `data load failed, errorMsg is `...
int errorCode;
if ( NOT_INITIALIZED.equals( errorMsg ) || errorMsg.contains( EXCEPTION_IV_RECALLNET_INVALIDATE ) )
{
errorCode = MaxAdapterError.ERROR_CODE_NOT_INITIALIZED;
}
else if ( NO_FILL_1.contains( errorMsg ) || NO_FILL_2.contains( errorMsg )
|| NO_FILL_3.contains( errorMsg ) || NO_FILL_4.contains( errorMsg ) || errorMsg.contains( EXCEPTION_RETURN_EMPTY ) )
{
errorCode = MaxAdapterError.ERROR_CODE_NO_FILL;
}
else if ( NETWORK_ERROR.equalsIgnoreCase( errorMsg ) || errorMsg.contains( NETWORK_IO_ERROR ) )
{
errorCode = MaxAdapterError.ERROR_CODE_NO_CONNECTION;
}
else if ( BAD_REQUEST.equalsIgnoreCase( errorMsg ) )
{
errorCode = MaxAdapterError.ERROR_CODE_BAD_REQUEST;
}
else if ( TIMEOUT.equalsIgnoreCase( errorMsg ) || errorMsg.contains( EXCEPTION_TIMEOUT ) )
{
errorCode = MaxAdapterError.ERROR_CODE_TIMEOUT;
}
else if ( errorMsg.contains( EXCEPTION_SIGN_ERROR ) || errorMsg.contains( EXCEPTION_UNIT_NOT_FOUND ) || errorMsg.contains( EXCEPTION_UNIT_ID_EMPTY ) || errorMsg.contains( EXCEPTION_UNIT_NOT_FOUND_IN_APP ) || errorMsg.contains( EXCEPTION_UNIT_ADTYPE_ERROR ) || errorMsg.contains( EXCEPTION_APP_ID_EMPTY ) || errorMsg.contains( EXCEPTION_APP_NOT_FOUND ) || errorMsg.contains( UNIT_ID_EMPTY ) )
{
errorCode = MaxAdapterError.ERROR_CODE_INVALID_CONFIGURATION;
}
else
{
errorCode = MaxAdapterError.ERROR_CODE_UNSPECIFIED;
}
return new MaxAdapterError( errorCode, errorMsg );
}
private BannerSize toBannerSize(final MaxAdFormat adFormat)
{
if ( adFormat == MaxAdFormat.BANNER || adFormat == MaxAdFormat.LEADER )
{
// Last two parameters are for custom width and height, so we can just use 0.
return new BannerSize( BannerSize.SMART_TYPE, 0, 0 );
}
else if ( adFormat == MaxAdFormat.MREC )
{
return new BannerSize( BannerSize.MEDIUM_TYPE, 0, 0 );
}
else
{
throw new IllegalArgumentException( "Unsupported ad format: " + adFormat );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment