Summary
Introduction
This article will show you how to add Smaato ads to your libGDX Android projects. You will be able to monetize your games with Banner, Interstitial and Rewarded Ads. This tutorial implies that you are already familiar with libGDX basics and how Android Views are handled. But there will be a short recap.
Just for a reference, the latest documentation is available on Smaato official website.
You will need:
- A libGDX Android Game Project
- Your Smaato account
Configuration
Add the following repository setup to your project’s main build.gradle
file:
buildscript {
repositories {
mavenCentral()
google()
jcenter()
maven { url "https://s3.amazonaws.com/smaato-sdk-releases/" }
}
}
...
allprojects {
repositories {
google()
jcenter()
maven {
url "https://s3.amazonaws.com/smaato-sdk-releases/"
}
}
}
Set the compile options to Java 8 and minSdkVersion to at least version 16, in android module build.gradle
file:
android {
defaultConfig {
minSdkVersion 16
...
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Add required dependencies to your application module build.gradle
file under project(“:android”) —> dependencies.
implementation 'com.smaato.android.sdk:smaato-sdk:21.5.3
If you’re using Proguard in your project, please add the following lines to your Proguard config file:
-keep public class com.smaato.sdk.** { *; }
-keep public interface com.smaato.sdk.** { *; }
Add the following permissions to application AndroidManifest.xml file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
If your application targets Android 5.0 (API level 21) or higher, then you need to add the following line to your application AndroidManifest.xml file:
<uses-feature android:name="android.hardware.location.network" />
The latest version of Smaato NextGenSDK has been validated against com.android.tools.build:gradle:3.5.4
and gradle-wrapper gradle-5.6.3-bin
Main build.gradle:
buildscript {
...
dependencies {
classpath 'com.android.tools.build:gradle:3.5.4'
}
}
The gradle-wrapper.properties:
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-bin.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
Recap
LibGDX Android game is created as a View. In order to add ads that are constantly displayed (like Banners) another view holding that should be used. In other words, a Relative Layout having both views should be created. You can see that in the following code snippet:
public class AndroidLauncher extends AndroidApplication {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout layout = new RelativeLayout(this);
layout.setLayoutParams(new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.addView(createGameView());
createAdView(layout);
setContentView(layout);
}
private View createGameView() {
View gameView = initializeForView(new MyGame(this), new AndroidApplicationConfiguration());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
gameView.setLayoutParams(params);
return gameView;
}
}
The only missing piece here is the createAdView
method that will be created in the next section.
Banner
In order to add Banner ads we will use com.smaato.sdk.banner.widget.BannerView
. As mentioned previously, the Banner view will reside in the same Relative Layout as the Game view.
public class AndroidLauncher extends AndroidApplication {
private static final String PUBLISHER_ID = "1100042525";
private static final String BANNER_AD_SPACE_ID = "130635694";
private BannerView smaatoBanner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout layout = new RelativeLayout(this);
layout.setLayoutParams(new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.addView(createGameView());
createAdView(layout);
setContentView(layout);
}
private void createAdView(RelativeLayout layout) {
SmaatoSdk.init(getApplication(), PUBLISHER_ID);
createSmaatoBanner();
layout.addView(smaatoBanner);
}
private void createSmaatoBanner() {
smaatoBanner = new BannerView(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
smaatoBanner.setLayoutParams(params);
smaatoBanner.setBackgroundColor(Color.TRANSPARENT);
smaatoBanner.setVisibility(View.INVISIBLE);
}
@Override
public void onDestroy() {
if (smaatoBanner != null) smaatoBanner.destroy();
super.onDestroy();
}
public void showBannerAds() {
runOnUiThread(() -> {
smaatoBanner.setVisibility(View.VISIBLE);
smaatoBanner.setEnabled(true);
smaatoBanner.loadAd(BANNER_AD_SPACE_ID, BannerAdSize.XX_LARGE_320x50);
});
}
public void hideBannerAds() {
runOnUiThread(() -> {
smaatoBanner.setVisibility(View.GONE);
smaatoBanner.setEnabled(false);
});
}
}
Let me walk you through this code snippet:
BannerView smaatoBanner
is kept as an instance variable, so an ad can be shown and hidden depending on the game lifecycleBannerView
should be always destroyed in order to release resources properly- The banner will be placed according to
RelativeLayout.LayoutParams
rules showBannerAds
/hideBannerAds
are supposed to be called as per the game lifecyclePUBLISHER_ID
andBANNER_AD_SPACE_ID
can be used during testing. Please, refer to Test Ads section for all available test ads configurations.
Interstitial
Unlike Banners, Interstitial ads are not constantly displayed on the screen. Such ads should be only shown at natural transition points in the flow of an app, like finishing/failing of a level or switching between the screens. Hence there is no need to have an additional view for Interstitial ads as they will typically occupy the whole screen and will be destroyed upon closing.
public class AndroidLauncher extends AndroidApplication {
private static final String PUBLISHER_ID = "1100042525";
private static final String INTERSTITIAL_AD_SPACE_ID = "130626426";
private InterstitialAd smaatoInterstitial;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout layout = new RelativeLayout(this);
layout.setLayoutParams(new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.addView(createGameView());
createAd();
setContentView(layout);
}
private void createAd() {
SmaatoSdk.init(getApplication(), PUBLISHER_ID);
requestSmaatoInterstitialAd();
}
public void showInterstitial() {
runOnUiThread(() -> {
if (smaatoInterstitial == null) {
requestSmaatoInterstitialAd();
return;
}
smaatoInterstitial.showAd(AndroidLauncher.this);
requestSmaatoInterstitialAd();
});
}
private void requestSmaatoInterstitialAd() {
Interstitial.loadAd(INTERSTITIAL_AD_SPACE_ID, new EventListener() {
@Override
public void onAdLoaded(@NonNull InterstitialAd interstitialAd) {
smaatoInterstitial = interstitialAd;
}
@Override
public void onAdFailedToLoad(@NonNull InterstitialRequestError interstitialRequestError) {
log(AndroidLauncher.class.getName(), "Smaato Interstitial failed to load; error: " + interstitialRequestError.getInterstitialError());
}
@Override
public void onAdError(@NonNull InterstitialAd interstitialAd, @NonNull InterstitialError interstitialError) {
}
@Override
public void onAdOpened(@NonNull InterstitialAd interstitialAd) {
}
@Override
public void onAdClosed(@NonNull InterstitialAd interstitialAd) {
}
@Override
public void onAdClicked(@NonNull InterstitialAd interstitialAd) {
}
@Override
public void onAdImpression(@NonNull InterstitialAd interstitialAd) {
}
@Override
public void onAdTTLExpired(@NonNull InterstitialAd interstitialAd) {
}
});
}
}
Let me walk you through this code snippet:
InterstitialAd smaatoInterstitial
is kept as an instance variable, so an ad can be shown depending on the game lifecycle- It is recommended to call
requestSmaatoInterstitialAd
on a game load, in order to have an ad preloaded from the start - There are multiple useful callbacks of
Interstitial.loadAd
that can be used depending on your use case showInterstitial
is supposed to be called as per the game lifecycle
Rewarded
Rewarded ads are visually similar to Interstitial ads as they typically occupy the whole screen. But workflow-wise they are completely different - such ads encourage users to interact with the ad content in exchange for in-app rewards, like extra lives, free coins or energy.
public class AndroidLauncher extends AndroidApplication {
private static final String PUBLISHER_ID = "1100042525";
private static final String REWARDED_INTERSTITIAL_AD_SPACE_ID = "130626428";
private RewardedInterstitialAd smaatoRewardedInterstitial;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout layout = new RelativeLayout(this);
layout.setLayoutParams(new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
layout.addView(createGameView());
createAd();
setContentView(layout);
}
private void createAd() {
SmaatoSdk.init(getApplication(), PUBLISHER_ID);
requestSmaatoRewardedInterstitialAd();
}
public void showRewarded() {
runOnUiThread(() -> {
if (smaatoRewardedInterstitial == null) {
requestSmaatoRewardedInterstitialAd();
return;
}
smaatoRewardedInterstitial.showAd();
requestSmaatoRewardedInterstitialAd();
});
}
private void requestSmaatoRewardedInterstitialAd() {
RewardedInterstitial.loadAd(REWARDED_INTERSTITIAL_AD_SPACE_ID, new EventListener() {
@Override
public void onAdLoaded(@NonNull RewardedInterstitialAd rewardedInterstitialAd) {
smaatoRewardedInterstitial = rewardedInterstitialAd;
}
@Override
public void onAdFailedToLoad(@NonNull RewardedRequestError rewardedRequestError) {
}
@Override
public void onAdError(@NonNull RewardedInterstitialAd rewardedInterstitialAd, @NonNull RewardedError rewardedError) {
}
@Override
public void onAdClosed(@NonNull RewardedInterstitialAd rewardedInterstitialAd) {
}
@Override
public void onAdClicked(@NonNull RewardedInterstitialAd rewardedInterstitialAd) {
}
@Override
public void onAdStarted(@NonNull RewardedInterstitialAd rewardedInterstitialAd) {
}
@Override
public void onAdReward(@NonNull RewardedInterstitialAd rewardedInterstitialAd) {
}
@Override
public void onAdTTLExpired(@NonNull RewardedInterstitialAd rewardedInterstitialAd) {
}
});
}
}
One more time, let me walk you through this code snippet:
RewardedInterstitialAd smaatoRewardedInterstitial
is kept as an instance variable, so an ad can be shown whenever a user initiates a rewarded ad flow in your game- It is recommended to call
requestSmaatoRewardedInterstitialAd
on a game load, in order to have an ad preloaded from the start - There are multiple useful callbacks of
RewardedInterstitial.loadAd
that you can be used depending on your use case showRewarded
is supposed to be called whenever a user initiates a rewarded ad flow in your game
Test Ads
Adspace ID | Type |
---|---|
130626424 | Rich Media |
130635694 | Static Image |
130635706 | MRAID |
130626426 | Rich Media / Video |
130626427 | Video |
130626428 | Rewarded |
Please, use Publisher Id 1100042525 with each of those adspaces.
Don’t forget to change the values to the production ones before the release!