In this blog, we will implement all major AdMob ad formats in an Android application:
Banner Ads
Interstitial Ads
Rewarded Ads
Native Ads
We will also understand how to properly control when and where ads should appear to avoid bad user experience and policy violations.
Create All Ad Units in AdMob
<string name="admob_app_id">ca-app-pub-3940256099942544~3347511713</string>
<string name="banner_ad_unit_id">ca-app-pub-3940256099942544/6300978111</string>
<string name="interstitial_ad_unit_id">ca-app-pub-3940256099942544/1033173712</string>
<string name="reward_ad_unit_id">ca-app-pub-3940256099942544/5224354917</string>
<string name="native_ad_unit_id">ca-app-pub-3940256099942544/2247696110</string>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="@string/admob_app_id" />
</application>
Implement Banner Ad
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ads:adSize="BANNER"
ads:adUnitId="@string/banner_ad_unit_id" />
MobileAds.initialize(this)
val adRequest = AdRequest.Builder().build()
binding.adView.loadAd(adRequest)
binding.adView.adListener = object : AdListener() {
override fun onAdLoaded() {
Log.d("Ads", "Banner Loaded")
}
override fun onAdFailedToLoad(error: LoadAdError) {
Log.d("Ads", "Failed: ${error.message}")
}
}
Implement Interstitial, Rewarded & Native
object AdManager {
private var interstitialAd: InterstitialAd? = null
private var rewardedAd: RewardedAd? = null
private var nativeAd: NativeAd? = null
fun loadInterstitial(context: Context, adUnitId: String, onLoaded: () -> Unit) {
val adRequest = AdRequest.Builder().build()
InterstitialAd.load(
context,
adUnitId,
adRequest,
object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) {
interstitialAd = ad
onLoaded()
}
override fun onAdFailedToLoad(error: LoadAdError) {
interstitialAd = null
}
}
)
}
fun showInterstitial(activity: Activity, onDismiss: () -> Unit) {
interstitialAd?.let { ad ->
ad.fullScreenContentCallback =
object : FullScreenContentCallback() {
override fun onAdDismissedFullScreenContent() {
interstitialAd = null
onDismiss()
}
}
ad.show(activity)
}
}
fun loadRewarded(
context: Context,
adUnitId: String,
onLoaded: () -> Unit
) {
val adRequest = AdRequest.Builder().build()
RewardedAd.load(
context,
adUnitId,
adRequest,
object : RewardedAdLoadCallback() {
override fun onAdLoaded(ad: RewardedAd) {
rewardedAd = ad
onLoaded()
}
override fun onAdFailedToLoad(error: LoadAdError) {
rewardedAd = null
}
}
)
}
fun showRewarded(
activity: Activity,
onRewardEarned: (RewardItem) -> Unit,
onDismiss: () -> Unit
) {
rewardedAd?.let { ad ->
ad.fullScreenContentCallback =
object : FullScreenContentCallback() {
override fun onAdDismissedFullScreenContent() {
rewardedAd = null
onDismiss()
}
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
rewardedAd = null
onDismiss()
}
}
ad.show(activity) { rewardItem ->
onRewardEarned(rewardItem)
}
} ?: run {
onDismiss()
}
}
fun loadNativeAd(
activity: Activity,
adUnitId: String,
container: ViewGroup
) {
// Purana ad destroy karo
nativeAd?.destroy()
nativeAd = null
val adLoader = AdLoader.Builder(activity, adUnitId)
.forNativeAd { ad ->
nativeAd = ad
val binding = CustomeAdsDesignBinding.inflate(
LayoutInflater.from(activity),
container,
false
)
binding.nativeAdView.headlineView = binding.adHeadline
binding.nativeAdView.bodyView = binding.adBody
binding.nativeAdView.callToActionView = binding.adCallToAction
binding.nativeAdView.iconView = binding.ivAds
// Set Data
binding.adHeadline.text = ad.headline
binding.adBody.text = ad.body
binding.adCallToAction.text = ad.callToAction
ad.icon?.let {
binding.ivAds.setImageDrawable(it.drawable)
binding.ivAds.visibility = View.VISIBLE
} ?: run {
binding.ivAds.visibility = View.GONE
}
// VERY IMPORTANT
binding.nativeAdView.setNativeAd(ad)
container.removeAllViews()
container.addView(binding.root)
}
.withAdListener(object : AdListener() {
override fun onAdFailedToLoad(error: LoadAdError) {
container.removeAllViews()
}
})
.build()
adLoader.loadAd(AdRequest.Builder().build())
}
fun destroyNative() {
nativeAd?.destroy()
nativeAd = null
}
}
Create CustomeAdsDesignBinding
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/_5sdp"
app:cardCornerRadius="@dimen/_10sdp"
app:cardElevation="@dimen/_5sdp">
<com.google.android.gms.ads.nativead.NativeAdView
android:id="@+id/native_ad_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_ads"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY" />
<TextView
android:id="@+id/adHeadline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/adBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/darker_gray"
android:textSize="14sp" />
<Button
android:id="@+id/adCallToAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Install" />
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
</androidx.cardview.widget.CardView>
</layout>
Load All Ads in Activity
class AdsActivity : AppCompatActivity() {
lateinit var binding: ActivityAdsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding = DataBindingUtil.setContentView(this, R.layout.activity_ads)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
initView()
}
private fun initView() {
MobileAds.initialize(this)
val adRequest = AdRequest.Builder().build()
binding.adView.loadAd(adRequest)
binding.adView.adListener = object : AdListener() {
override fun onAdLoaded() {
Log.d("Ads", "Banner Loaded")
}
override fun onAdFailedToLoad(error: LoadAdError) {
Log.d("Ads", "Failed: ${error.message}")
}
}
//**{Interstitial Ads}**\\
binding.btnInterstitialLoadAds.isEnabled = false
binding.btnInterstitialLoadAds.alpha = 0.5f
// Load first time
AdManager.loadInterstitial(
this,
getString(R.string.interstitial_ad_unit_id)
) {
binding.btnInterstitialLoadAds.isEnabled = true
binding.btnInterstitialLoadAds.alpha = 1f
}
binding.btnInterstitialLoadAds.setOnClickListener {
binding.btnInterstitialLoadAds.isEnabled = false
binding.btnInterstitialLoadAds.alpha = 0.5f
AdManager.showInterstitial(this) {
// After dismiss → preload next ad
AdManager.loadInterstitial(
this,
getString(R.string.interstitial_ad_unit_id)
) {
binding.btnInterstitialLoadAds.isEnabled = true
binding.btnInterstitialLoadAds.alpha = 1f
}
}
}
//**{Reward Ads}**\\
AdManager.loadRewarded(
this,
getString(R.string.reward_ad_unit_id)
) {
binding.btnRewardedLoadAds.isEnabled = true
binding.btnRewardedLoadAds.alpha = 1f
}
binding.btnRewardedLoadAds.setOnClickListener {
binding.btnRewardedLoadAds.isEnabled = false
binding.btnRewardedLoadAds.alpha = 0.5f
AdManager.showRewarded(
this,
onRewardEarned = { rewardItem ->
val amount = rewardItem.amount
val type = rewardItem.type
Toast.makeText(this, "Earned $amount $type", Toast.LENGTH_SHORT).show()
},
onDismiss = {
// Preload next rewarded ad
AdManager.loadRewarded(
this,
getString(R.string.reward_ad_unit_id)
) {
binding.btnRewardedLoadAds.isEnabled = true
binding.btnRewardedLoadAds.alpha = 1f
}
}
)
}
AdManager.loadNativeAd(
this,
getString(R.string.native_ad_unit_id),
binding.flContainer
)
}
override fun onResume() {
super.onResume()
AdManager.destroyNative()
}
}
📌 Conclusion
Implementing all ad formats correctly helps maximize revenue while maintaining good UX. A well-structured ad strategy can significantly improve both user retention and earnings.
Top comments (0)