How to Implement Ads in an Android App

Mobile ads offer a powerful way to monetize your apps. This blog will show you how to implement four types of ads in Android including: banner ads, interstitial ads, native ads and rewarded ads. We have implemented ads in our to-do list mobile app Colorful Reminder as shown in the video below, check it out if you’re interested. Alright, let’s get started.
Introduction to Ads in Android
Warning!
Whenever you are testing ads code, always make sure you are using a test ad id provided by Google as we will be doing in this tutorial. Do not use the real ad ids you created in your Admob account as you risk getting your account suspended if you click your own ads.
Here is a quote from Google: “Publishers may not click their own ads or use any means to inflate impressions and/or clicks artificially, including manual methods. Testing your own ads by clicking on them is not allowed.“ You you can find the statement here: https://support.google.com/admob/answer/2753860#Invalid_clicks.
When you’re done testing and developing your app, replace the test ad ids with your real ad ids before you release your app.
Before diving into the technical details, let’s get a brief overview of the types of ads we will be covering in this blog.
Banner Ads
Banner ads are the simplest form of ads.They are rectangular units, usually placed at the bottom or top of the app view. They are the least intrusive as they occupy a fairly small part of the screen. You can find Google’s banner ads guidance here: https://support.google.com/admob/answer/6128877.
Interstitial Ads
Interstitial ads cover the whole screen when they are displayed. They are very common in mobile games. When they appear, they can show a video or an image, commonly with a call to action such as a button to download an app from Google Play. The user has the choice between clicking the ad or closing it. They’re typically displayed during pauses or breaks, such as after winning a level in a game. You can find Google’s Interstitial ads’ guidance here https://support.google.com/admob/answer/6066980.
Native Ads
Native ads allow the developer to customize the appearance of the ad so that it blends seamlessly with the app’s UI or theme. Unlike banner or interstitial ads, which have predefined layouts, native ads provide flexibility to developers by allowing them to choose the ads’ colors, fonts, placements and more. However, always make sure to follow the guidelines that Google sets for native ads, you can find them here: https://support.google.com/admob/answer/6329638.
Rewarded Ads
Rewarded ads offer the user a reward for doing an action such as watching a video, taking a survey or playing a game. For instance, many mobile games offer the player extra coins or points by watching a video ad. You can find Google’s policies regarding rewarded ads here https://support.google.com/admob/answer/7313578.
More Details
This is a very brief introduction to mobile ads. If you would like more details, visit Google’s documentation on this link: https://developers.google.com/admob/android/quick-start.
Android Studio Project Setup
First we start by creating a new project in Android Studio. We will be using the version Ladybug | 2024.2.1 Patch 1. Follow these steps to create an empty project:
1. Click on File -> New -> New Project.
2. Choose Phone and Tablet on the left menu and select No Activity on the right menu. Then click Next.
3. In the next window, set the following:
- In the Name field, set the app name to AdsTutorial.
- Leave the Package name as is, it should be automatically set to com.example.adstutorial.
- Set the location of your project in the Save location field to any location of your choosing.
- We will be using Java for this blog, so set the Language box to Java.
- Set the Minimum SDK to your liking, we leave it at API 24 Nougat.
- Set the Build configuration language, we will leave it as recommended by Android Studio to Kotlin DSL.
4. Click Finish and wait until Android Studio is done importing and setting up the project.
Import the Google Mobile Ads SDK
To import the ads sdk, follow these steps:
1. Open the file settings.gradle.kts (Project Settings) by double clicking it.
2. Make sure google() and mavenCentral() are included inside the pluginManagement and dependencyResolutionManagement sections as highlighted in the code below. Your file should already have these lines by default, but check just in case and add them if they are missing.
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "AdsTutorial"
include(":app")
3. Open the build.gradle.kts (Module :app) file.
4. Paste the line implementation("com.google.android.gms:play-services-ads:24.2.0")
inside the dependencies section.
plugins {
alias(libs.plugins.android.application)
}
android {
namespace = "com.example.adstutorial"
compileSdk = 34
defaultConfig {
applicationId = "com.example.adstutorial"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
dependencies {
implementation(libs.appcompat)
implementation(libs.material)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
implementation("com.google.android.gms:play-services-ads:24.2.0")
}
5. Click Sync now on the top right and wait for it to finish syncing.

Create the Code and User Interface (UI)
Now we create the UI, we will add a button for each type of ads: banner ads, interstitial ads, native ads and rewarded ads. When a button is clicked, it will load and display the corresponding ad. Follow the following steps:
1. Select File -> New -> Activity -> Empty Views Activity. This will create the main activity of our app, which is basically the starting point when the app is loaded.
2. In the next window, set the following:
- Set Activity Name to MainActivity.
- Check the Generate a Layout File checkbox.
- Set Layout Name to activity_main.
- Check the Launcher Activity checkbox. It will set this activity as the first screen displayed when the app is launched.
- Leave Package name as is, it should be already set to com.example.adstutorial.
- Set Source Language to Java.
- Set Target Source Set to main.
3. Click Finish. You will now have a MainActivity.Java file along with the activity_main.xml file which contains the UI.
Open the libs.versions.toml file.
Now try to build the project, click the hammer icon at the top right as shown below.
If your project builds without any error, then you can skip this step. However, If you get this error “Dependency androidx.activity:activity:1.10.1′ requires libraries and applications that depend on it to compile against version 35 or later of the Android APIs.” then set the activity version to 1.8.0 as highlighted below.
[versions]
agp = "8.7.1"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
appcompat = "1.7.0"
material = "1.12.0"
activity = "1.8.0"
constraintlayout = "2.2.1"
[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
If applicable, click Sync now as we did earlier and wait for it to finish. If you build the project now, it should not give you any errors.
Now we need to set an application id in the manifest file. We will be using the sample one provided by Google, you can find it here: https://developers.google.com/admob/android/quick-start#java. In your real app, you would get this app id from your Admob account and replace this sample one. To do this, open the AndroidManifest.xml.
Add the highlighted code below.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AdsTutorial"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713"/>
</application>
</manifest>
Warning!
When you use your real ads from Admob, replace this application id with your real app id. You can find it in your Admob account.
Open the activity_main.xml file, then click on the Code button on the top right as shown highlighted in red in the image below. This will switch to the XML view of the layout file.

Replace the XML code you have inside activity_main.xml with the following code.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/show_banner_ad_button"
android:layout_width="200dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:text="Show Banner Ad"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/show_interstitial_ad_button"
android:layout_width="200dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:text="Show Interstitial Ad"
app:layout_constraintTop_toBottomOf="@id/show_banner_ad_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/show_native_ad_button"
android:layout_width="200dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:text="Show Native Ad"
app:layout_constraintTop_toBottomOf="@id/show_interstitial_ad_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/show_rewarded_ad_button"
android:layout_width="200dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:text="Show Rewarded Ad"
app:layout_constraintTop_toBottomOf="@id/show_native_ad_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<FrameLayout
android:id="@+id/banner_ad_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_alignParentBottom="true"
app:layout_constraintBottom_toBottomOf="parent"/>
<FrameLayout
android:id="@+id/native_ad_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:layout_constraintTop_toBottomOf="@+id/show_rewarded_ad_button"/>
</androidx.constraintlayout.widget.ConstraintLayout>
It should look like this:
Here’s some basic information about this layout:
- The parent container is a ConstraintLayout, it allows you to place items relative to other items. For example, the interstitial ad button is placed below the banner ad button using the line
app:layout_constraintTop_toBottomOf="@id/show_banner_ad_button"
. - Inside the layout are four buttons, one for each type of ad. When clicked, it will load and display the corresponding ad.
- After the buttons, there are two FrameLayout components, one for the banner ad and the other for the native ad. These are just containers, they only reserve a space for the ads and currently do not display anything. Later, we will add components to them in code.
Now it’s time to code. First, let’s create some member and static variables that we will need. Copy the following code and paste it In the MainActivity class inside the MainActivity.java file.
package com.example.adstutorial;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdLoader;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import com.google.android.gms.ads.rewarded.RewardItem;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;
public class MainActivity extends AppCompatActivity {
// Tag used to filter logs in the logcat
private static final String TAG = "MainActivity";
// For banner ad
private AdView bannerAd;
// for interstitial ad
private InterstitialAd interstitialAd;
// For native ad
private NativeAd nativeAd;
// For rewarded ad
private RewardedAd rewardedAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
}
}
Next we create four empty methods that will later be used to request the ads. We leave them empty as placeholders for now so that we don’t get any compile errors when we set up our buttons below. We will fill the functions one by one later on. Copy the highlighted methods and paste them in the MainActivity class inside the MainActivity.java class.
package com.example.adstest;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdLoader;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import com.google.android.gms.ads.rewarded.RewardItem;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;
public class MainActivity extends AppCompatActivity {
// Tag used to filter logs in the logcat
private static final String TAG = "MainActivity";
// For banner ad
private AdView bannerAd;
// for interstitial ad
private InterstitialAd interstitialAd;
// For native ad
private NativeAd nativeAd;
// For rewarded ad
private RewardedAd rewardedAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
}
private void RequestBannerAdd(){
}
private void RequestInterstitialAd(){
}
private void RequestNativeAd(){
}
private void RequestRewardedAd(){
}
}
Now we initialize the Google Mobile Ads SDK and set click listeners to our buttons, add the highlighted code inside the onCreate method.
package com.example.adstest;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdLoader;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import com.google.android.gms.ads.rewarded.RewardItem;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;
public class MainActivity extends AppCompatActivity {
// Tag used to filter logs in the logcat
private static final String TAG = "MainActivity";
// For banner ad
private AdView bannerAd;
// for interstitial ad
private InterstitialAd interstitialAd;
// For native ad
private NativeAd nativeAd;
// For rewarded ad
private RewardedAd rewardedAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
// Initialize the ads SDK. Only need to do it once.
MobileAds.initialize(this, initializationStatus -> {});
// Create the click listeners for each button.
Button showBannerAdButton = findViewById(R.id.show_banner_ad_button);
showBannerAdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RequestBannerAdd();
}
});
Button showInterstitialAdButton = findViewById(R.id.show_interstitial_ad_button);
showInterstitialAdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RequestInterstitialAd();
}
});
Button showNativeAdButton = findViewById(R.id.show_native_ad_button);
showNativeAdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RequestNativeAd();
}
});
Button rewardedAdButton = findViewById(R.id.show_rewarded_ad_button);
rewardedAdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RequestRewardedAd();
}
});
}
private void RequestBannerAdd(){
}
private void RequestInterstitialAd(){
}
private void RequestNativeAd(){
}
private void RequestRewardedAd(){
}
}
The line MobileAds.initialize(this, initializationStatus -> {})
initializes the ads SDK. You should only do this once in your code, this is why putting it in the onCreate method of your launcher activity is the best place.
The rest of the code simply gets a reference to the buttons we created earlier in activity_main.xml by searching for their id. Then we set the click listener using setOnClickListener so everytime the button is clicked, the onClick method is executed. Inside onClick, we request the proper ad depending on the button clicked by calling the empty methods we created earlier.
Banner Ad Implementation
Now we implement the empty methods we created earlier, which will load and display the ad. We start with RequestBannerAdd, copy the code below and paste it in the class to replace the empty method.
// Requests and displays the banner ad.
private void RequestBannerAdd(){
// If Ad already exists, remove it first before creating a new one
DestroyBannerAd();
FrameLayout adViewContainer = findViewById(R.id.banner_ad_container);
bannerAd = new AdView(this);
// Always Use the test ad id when testing.
bannerAd.setAdUnitId("ca-app-pub-3940256099942544/9214589741");
bannerAd.setAdSize(AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, 360));
adViewContainer.removeAllViews();
adViewContainer.addView(bannerAd);
AdRequest adRequest = new AdRequest.Builder().build();
// Request the ad.
bannerAd.loadAd(adRequest);
}
// Destroys the banner ad.
private void DestroyBannerAd(){
if(bannerAd != null){
if (bannerAd.getParent() instanceof ViewGroup) {
((ViewGroup) bannerAd.getParent()).removeView(bannerAd);
}
bannerAd.destroy();
bannerAd = null;
}
}
Here’s what it does:
- DestroyBannerAd is called to remove the ad if it has already been created, for example, if you have already clicked the button and you click it again. It also frees up memory and prevents memory leaks.
- Creates an AdView and sets the unit id using the method setAdUnitId. The id that is passed is the test ad id that we mentioned earlier.
- Finally, the bannerAd.loadAd line loads the ad.
If you now run the app and click the show banner ad button, after you wait for a few seconds, the banner ad will be shown at the bottom of the screen. If it doesn’t, then check the logcat in Android Studio and see if there were any errors.
Interstitial Ad Implementation
Let’s implement the interstitial ad now. Copy and paste the code below to replace the empty RequestInterstitialAd method.
private void RequestInterstitialAd(){
// If Ad already exists, remove it first before creating a new one.
DestroyInterstitialAd();
AdRequest adRequest = new AdRequest.Builder().build();
// Always Use the test ad id when testing.
InterstitialAd.load(this, "ca-app-pub-3940256099942544/1033173712", adRequest, new InterstitialAdLoadCallback() {
// Callback that is called when it's loaded.
@Override
public void onAdLoaded(@NonNull InterstitialAd interstitialAd){
MainActivity.this.interstitialAd = interstitialAd;
MainActivity.this.interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
// Callback called when ad is dismissed.
@Override
public void onAdDismissedFullScreenContent() {
super.onAdDismissedFullScreenContent();
Log.d(TAG, "Ad was dismissed");
// Destroy the ad when dismissed by the user.
DestroyInterstitialAd();
}
// Callback called when ad failed show.
@Override
public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) {
super.onAdFailedToShowFullScreenContent(adError);
Log.d(TAG, "Failed to show ad");
// Destroy the ad when loading fails.
DestroyInterstitialAd();
}
});
// Show the interstitial ad
MainActivity.this.interstitialAd.show(MainActivity.this);
Log.i(TAG, "Interstitial ad loaded");
}
// Callback that is called when ad fails to load.
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
super.onAdFailedToLoad(loadAdError);
Log.d(TAG, "Failed to load interstitial ad: " + loadAdError.toString());
// Destroy the ad when it fails to load
DestroyInterstitialAd();
}
});
}
// Destroys the interstitial ad.
private void DestroyInterstitialAd(){
interstitialAd = null;
}
The logic of this code is a bit different than banner ads. The code loads the app using the InterstitialAd.load method and passes it a test ad id as we did before. But this time, we have to override the callbacks. Once the ad is loaded successfully, onAdLoaded is called. Then the ad can be shown. If the ad fails to load, onAdFailedToLoad will be called.
If you press the show interstitial ad button and wait a bit, it will show a full screen test ad and a button to close it.
Native Ad Implementation
Native ads let you customize the appearance of your ads, so we need to define our own UI. Create a new layout by selecting File -> New -> XML -> Layout XML File.
Set the Layout File Name to native_ad_layout and leave the Root Tag as is, we will overwrite the file anyways so it doesn’t matter which you choose.
Then click Finish. The file will be added to the res folder.
Open the native_ad_layout.xml file and paste the following XML in it.
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/native_adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/black">
<TextView
android:id="@+id/native_ad_headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:textColor="@color/white"
/>
</com.google.android.gms.ads.nativead.NativeAdView>
The main container is of type NativeAdView, inside the container you can customize how your ad looks. Just for illustration purposes, we only included a TextView with a white text and black background, and we will set it from code. However, you can set many other things like icons, images and more.
Go back to MainActivity class, and paste the following code to replace the empty RequestNativeAd method.
// Requests and displays the native ad.
private void RequestNativeAd(){
// If Ad already exists, remove it first before creating a new one.
DestroyNativeAd();
// Always Use the test ad id when testing.
AdLoader adLoader = new AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110").forNativeAd(new NativeAd.OnNativeAdLoadedListener() {
// Callback that is called when it's loaded.
@Override
public void onNativeAdLoaded(@NonNull NativeAd nativeAd) {
Log.d(TAG, "Native ad loaded.");
// If callback occurs after native ad is destroyed.
if (isDestroyed()) {
DestroyNativeAd();
return;
}
MainActivity.this.nativeAd = nativeAd;
ViewGroup parent = findViewById(R.id.native_ad_container);
NativeAdView adView = (NativeAdView) getLayoutInflater().inflate(R.layout.native_ad_layout, null);
// Set the TextView's text.
if(nativeAd.getHeadline() != null){
TextView headLineText = adView.findViewById(R.id.native_ad_headline);
headLineText.setText(nativeAd.getHeadline());
adView.setHeadlineView(headLineText);
}
adView.setNativeAd(nativeAd);
parent.removeAllViews();
parent.addView(adView);
}
}).withAdListener(new AdListener() {
// Callback that's called when ad fails to load.
@Override
public void onAdFailedToLoad(LoadAdError adError) {
Log.e(TAG, "Failed to load native add: " + adError.getMessage());
DestroyNativeAd();
}
}).build();
// Load the ad
adLoader.loadAd(new AdRequest.Builder().build());
}
// Destroys the native ad.
private void DestroyNativeAd(){
if(nativeAd != null){
nativeAd.destroy();
}
}
This is pretty similar to the interstitial ad, we request the ad and then wait for it to load, then display the ad. The main difference is because we set our own UI, we have to manually set the TextView we created in our layout using the setHeadlineView method.
If you click the show native ad button and wait a bit, the test ad will show a white text on a black background.
Note
This is just an example, review Google’s native ads guidelines here https://support.google.com/admob/answer/6329638 to make sure your native ad meets the requirements.
Rewarded Ad Implementation
Rewarded ads take the whole screen and prompt you to watch a video or do another action, and in return, the user is rewarded with coins or points or other types of reward. Copy the code below to implement it to replace the empty RequestRewardedAd method.
// Requests and displays the rewarded ad.
private void RequestRewardedAd(){
// If Ad already exists, remove it first before creating a new one.
DestroyRewardedAd();
AdRequest adRequest = new AdRequest.Builder().build();
// Always Use the test ad id when testing.
RewardedAd.load(this, "ca-app-pub-3940256099942544/5224354917", adRequest, new RewardedAdLoadCallback() {
// Callback that's called when ad fails to load.
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
Log.d(TAG, "Failed to load rewarded ad: " + loadAdError.toString());
DestroyRewardedAd();
}
// Callback that is called when it's loaded.
@Override
public void onAdLoaded(@NonNull RewardedAd ad) {
Log.d(TAG, "Rewarded ad was loaded.");
rewardedAd = ad;
Activity activityContext = MainActivity.this;
// show the ad.
rewardedAd.show(activityContext, new OnUserEarnedRewardListener() {
// Callback called when the user receives the reward.
@Override
public void onUserEarnedReward(@NonNull RewardItem rewardItem) {
Log.d(TAG, "The user earned the reward.");
int rewardAmount = rewardItem.getAmount();
String rewardType = rewardItem.getType();
Toast.makeText(activityContext, "The user earned the reward: " + rewardAmount + " " + rewardType, Toast.LENGTH_LONG).show();
}
});
rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
// Callback called when ad is dismissed.
@Override
public void onAdDismissedFullScreenContent() {
Log.d(TAG, "Ad dismissed fullscreen content.");
DestroyRewardedAd();
}
// Callback called when ad failed to show.
@Override
public void onAdFailedToShowFullScreenContent(AdError adError) {
Log.e(TAG, "Ad failed to show fullscreen content.");
DestroyRewardedAd();
}
});
}
});
}
// Destroys the rewarded ad.
private void DestroyRewardedAd(){
rewardedAd = null;
}
Again, as with native and interstitial ads, the code makes the request for an ad and waits for it to load. When loaded successfully, the code enters the onAdLoaded method. The main difference here is the onUserEarnedReward is called once the user is rewarded. Here, we only display a message using a Toast. In a real app, like a game, this is where you would reward the player with extra coins or points.
If you click the show rewarded ad and wait a bit, you will get a full screen ad. If you watch the video to the end, a Toast will be displayed saying: “The user earned the reward” and some number of coins.
Full Code
Here’s the full code for MainActivity.java:
package com.example.adstutorial;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdLoader;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import com.google.android.gms.ads.rewarded.RewardItem;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;
public class MainActivity extends AppCompatActivity {
// Tag used to filter logs in the logcat
private static final String TAG = "MainActivity";
// For banner ad
private AdView bannerAd;
// for interstitial ad
private InterstitialAd interstitialAd;
// For native ad
private NativeAd nativeAd;
// For rewarded ad
private RewardedAd rewardedAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
// Initialize the ads SDK. Only need to do it once.
MobileAds.initialize(this, initializationStatus -> {});
// Create the click listeners for each button.
Button showBannerAdButton = findViewById(R.id.show_banner_ad_button);
showBannerAdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RequestBannerAdd();
}
});
Button showInterstitialAdButton = findViewById(R.id.show_interstitial_ad_button);
showInterstitialAdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RequestInterstitialAd();
}
});
Button showNativeAdButton = findViewById(R.id.show_native_ad_button);
showNativeAdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RequestNativeAd();
}
});
Button rewardedAdButton = findViewById(R.id.show_rewarded_ad_button);
rewardedAdButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RequestRewardedAd();
}
});
}
// Requests and displays the banner ad
private void RequestBannerAdd(){
// If Ad already exists, remove it first before creating a new one
DestroyBannerAd();
FrameLayout adViewContainer = findViewById(R.id.banner_ad_container);
bannerAd = new AdView(this);
// Always Use the test ad id when testing.
bannerAd.setAdUnitId("ca-app-pub-3940256099942544/9214589741");
bannerAd.setAdSize(AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, 360));
adViewContainer.removeAllViews();
adViewContainer.addView(bannerAd);
AdRequest adRequest = new AdRequest.Builder().build();
// Request the ad.
bannerAd.loadAd(adRequest);
}
// Destroys the banner ad.
private void DestroyBannerAd(){
if(bannerAd != null){
if (bannerAd.getParent() instanceof ViewGroup) {
((ViewGroup) bannerAd.getParent()).removeView(bannerAd);
}
bannerAd.destroy();
bannerAd = null;
}
}
private void RequestInterstitialAd(){
// If Ad already exists, remove it first before creating a new one.
DestroyInterstitialAd();
AdRequest adRequest = new AdRequest.Builder().build();
// Always Use the test ad id when testing.
InterstitialAd.load(this, "ca-app-pub-3940256099942544/1033173712", adRequest, new InterstitialAdLoadCallback() {
// Callback that is called when it's loaded.
@Override
public void onAdLoaded(@NonNull InterstitialAd interstitialAd){
MainActivity.this.interstitialAd = interstitialAd;
MainActivity.this.interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
// Callback called when ad is dismissed.
@Override
public void onAdDismissedFullScreenContent() {
super.onAdDismissedFullScreenContent();
Log.d(TAG, "Ad was dismissed");
// Destroy the ad when dismissed by the user.
DestroyInterstitialAd();
}
// Callback called when ad failed show.
@Override
public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) {
super.onAdFailedToShowFullScreenContent(adError);
Log.d(TAG, "Failed to show ad");
// Destroy the ad when loading fails.
DestroyInterstitialAd();
}
});
// Show the interstitial ad
MainActivity.this.interstitialAd.show(MainActivity.this);
Log.i(TAG, "Interstitial ad loaded");
}
// Callback that is called when ad fails to load.
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
super.onAdFailedToLoad(loadAdError);
Log.d(TAG, "Failed to load interstitial ad: " + loadAdError.toString());
// Destroy the ad when it fails to load
DestroyInterstitialAd();
}
});
}
// Destroys the interstitial ad.
private void DestroyInterstitialAd(){
interstitialAd = null;
}
// Requests and displays the native ad.
private void RequestNativeAd(){
// If Ad already exists, remove it first before creating a new one.
DestroyNativeAd();
// Always Use the test ad id when testing.
AdLoader adLoader = new AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110").forNativeAd(new NativeAd.OnNativeAdLoadedListener() {
// Callback that is called when it's loaded.
@Override
public void onNativeAdLoaded(@NonNull NativeAd nativeAd) {
Log.d(TAG, "Native ad loaded.");
// If callback occurs after native ad is destroyed.
if (isDestroyed()) {
DestroyNativeAd();
return;
}
MainActivity.this.nativeAd = nativeAd;
ViewGroup parent = findViewById(R.id.native_ad_container);
NativeAdView adView = (NativeAdView) getLayoutInflater().inflate(R.layout.native_ad_layout, null);
// Set the TextView's text.
if(nativeAd.getHeadline() != null){
TextView headLineText = adView.findViewById(R.id.native_ad_headline);
headLineText.setText(nativeAd.getHeadline());
adView.setHeadlineView(headLineText);
}
adView.setNativeAd(nativeAd);
parent.removeAllViews();
parent.addView(adView);
}
}).withAdListener(new AdListener() {
// Callback that's called when ad fails to load.
@Override
public void onAdFailedToLoad(LoadAdError adError) {
Log.e(TAG, "Failed to load native add: " + adError.getMessage());
DestroyNativeAd();
}
}).build();
// Load the ad
adLoader.loadAd(new AdRequest.Builder().build());
}
// Destroys the native ad.
private void DestroyNativeAd(){
if(nativeAd != null){
nativeAd.destroy();
}
}
// Requests and displays the rewarded ad.
private void RequestRewardedAd(){
// If Ad already exists, remove it first before creating a new one.
DestroyRewardedAd();
AdRequest adRequest = new AdRequest.Builder().build();
// Always Use the test ad id when testing.
RewardedAd.load(this, "ca-app-pub-3940256099942544/5224354917", adRequest, new RewardedAdLoadCallback() {
// Callback that's called when ad fails to load.
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
Log.d(TAG, "Failed to load rewarded ad: " + loadAdError.toString());
DestroyRewardedAd();
}
// Callback that is called when it's loaded.
@Override
public void onAdLoaded(@NonNull RewardedAd ad) {
Log.d(TAG, "Rewarded ad was loaded.");
rewardedAd = ad;
Activity activityContext = MainActivity.this;
// show the ad.
rewardedAd.show(activityContext, new OnUserEarnedRewardListener() {
// Callback called when the user receives the reward.
@Override
public void onUserEarnedReward(@NonNull RewardItem rewardItem) {
Log.d(TAG, "The user earned the reward.");
int rewardAmount = rewardItem.getAmount();
String rewardType = rewardItem.getType();
Toast.makeText(activityContext, "The user earned the reward: " + rewardAmount + " " + rewardType, Toast.LENGTH_LONG).show();
}
});
rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
// Callback called when ad is dismissed.
@Override
public void onAdDismissedFullScreenContent() {
Log.d(TAG, "Ad dismissed fullscreen content.");
DestroyRewardedAd();
}
// Callback called when ad failed to show.
@Override
public void onAdFailedToShowFullScreenContent(AdError adError) {
Log.e(TAG, "Ad failed to show fullscreen content.");
DestroyRewardedAd();
}
});
}
});
}
// Destroys the rewarded ad.
private void DestroyRewardedAd(){
rewardedAd = null;
}
}
Real Ads
You’ve seen in this blog how to display test ads. For real ads, you will need to create an Admob account https://admob.google.com/home/, which is a Google platform that allows developers to create and manage ad units. Then, you will simply copy the real ad ids from your account and replace the test ad ids. You will also have to copy the app id from your account and replace the test app id in the AndroidManifest.xml.
Privacy Considerations
When implementing ads in your app, you need to be aware of some privacy issues. Many ad networks collect user data to serve personalized ads, i.e. ads that are tailored to individual users based on their online activity, interests, and demographic information. To reduce data collection, you can serve only non-personalized ads, meaning ads not based on individual user data, such as browsing history or interests. Disabling personalized ads is outside of the scope of this blog, so check how you can do it from your Admob account or from inside the app itself.
Useful Links
Here are a few links to Google’s documentation that will help you follow the guidelines and optimize your ads:
- Quick start tutorials: https://developers.google.com/admob/android/quick-start .
- Implementation guidance: https://support.google.com/admob/answer/2936217.
- Banner ad guidance: https://support.google.com/admob/answer/6128877.
- Interstitial ad guidance: https://support.google.com/admob/answer/6066980.
- Native ad guidelines: https://support.google.com/admob/answer/6329638 .
- Invalid clicks and impressions: https://support.google.com/admob/answer/2753860#Invalid_clicks.
- Policies for ad units that offer rewards: https://support.google.com/admob/answer/7313578.
Conclusion
Ads are a great way to monetize your app, and fairly easy to implement on Android. While generating revenue is crucial, so is user experience. Make sure your ads are not intrusive and do not degrade user experience. If you use interstitial ads, be mindful about when to show the them to avoid frustrating users. Finally, always review the privacy compliance of your app. If you enjoyed this blog, then please checkout our apps and products below.
We Need Your Help!
Please check out our apps and games, we also have a few Unity icon packs in the Unity Asset Store if you need them for your game or app. Your support is very much appreciated!
You Might Also Like
- Glossy Icons Pack Available in the Unity Asset Store.
- Flat Icons Pack Available in the Unity Asset Store.
- How to Implement In-App Purchases in an Android App.
- Note Chain Available Now!
- Tips for Developing a Game as a Solo Developer.
- How to Make a 2D Rain Effect in the Unity Engine.
- Tips for Debugging Unity Games.
- How to Improve the Performance of Your Unity Game.
- Thirsty Plant Available Now!
- How to Implement In-App Purchases with Unity IAP.
- How to Create a Dripping Liquid Effect in the Unity Engine.