SmartAds is a professional-grade, lightweight, and developer-friendly Android wrapper for the Google Mobile Ads SDK (AdMob). It streamlines complex ad integrations into simple, lifecycle-aware components, allowing you to focus on building features while we handle the monetization.
Integrating ads can be messyβhandling context, memory leaks, pre-fetching, and mediation verification often leads to boilerplate-heavy code. SmartAds solves this by:
- Reducing Boilerplate: From 150+ lines of AdMob code to just 1-2 lines.
- Lifecycle Safety: Built-in protection against Activity-based memory leaks.
- Smart Pre-fetching: Automatically caches ads so they're ready the moment you need them.
- House Ads Fallback: Never miss an impressionβshow your own promotions if the network fails.
- β
Unified Initialization: One-time setup in your
Applicationclass. - π± Complete Format Support: App Open, Banner (Adaptive/Collapsible), Interstitial, Rewarded, and Native Ads.
- π οΈ Seamless Mediation: Dedicated support for Meta, AppLovin, and Unity Ads.
- π House Ads System: Native fallbacks for internal cross-promotion.
- π Privacy First: Built-in Google UMP (GDPR/CCPA) consent management.
- π§ͺ Test Mode: Automatically handles AdMob Test IDs during development.
- π Debug Suite: Integrated Ad Inspector, Mediation Test Suite, and detailed logging.
- π° Paid Event Tracking: Simple hook for revenue analytics (Firebase, AppsFlyer, etc.).
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}dependencies {
implementation 'com.github.partharoypc:SmartAds:5.3.0'
implementation 'com.google.android.gms:play-services-ads:24.9.0'
// Note: Mediation adapters are NOT included by default.
// Only add the networks you actually use (see Mediation Setup section below)
}<!-- Ad And Internet Permission -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<!-- Admob Meta Data (inside the application tag) -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>Before you start, make sure you've:
- Added the JitPack repository.
- Added the
SmartAdsandplay-services-adsdependencies. - Added your AdMob App ID to
AndroidManifest.xml. - Initialized the SDK in your
Applicationclass.
Initialize in your Application class using SmartAdsConfig.
SmartAdsConfig config = new SmartAdsConfig.Builder()
.setAdsEnabled(true) // Global switch to enable/disable ads
.setTestModeEnabled(true) // Uses Google Test IDs when enabled
.setAdMobAppOpenId("AD_UNIT_ID")
.setAdMobBannerId("AD_UNIT_ID")
.setAdMobInterstitialId("AD_UNIT_ID")
.setAdMobRewardedId("AD_UNIT_ID")
.setAdMobNativeId("AD_UNIT_ID")
.setUseUmpConsent(true) // Enable GDPR/UMP consent flow
.setFrequencyCapSeconds(30) // Min time between full-screen ads
.build();
SmartAds.initialize(this, config);| Method | Description |
|---|---|
setLoggingEnabled(boolean) |
Enable internal debug logs. |
setCollapsibleBannerEnabled(boolean) |
Enable collapsible banner feature. |
setFacebookMediationEnabled(boolean) |
Verification for Meta Audience Network. |
setAppLovinMediationEnabled(boolean) |
Verification for AppLovin. |
setUnityMediationEnabled(boolean) |
Verification for Unity Ads. |
setLoadingDialogText(String headline, String sub) |
Custom headline and sub-text for valid loading dialog. |
setLoadingDialogColor(bg, text) |
Custom background and text/headline colors. |
setLoadingDialogSubTextColor(int) |
Custom color for the sub-text (default is secondary text color). |
setLoadingDialogProgressColor(int) |
Custom color for the circular progress indicator. |
setMaxAdContentRating(String) |
Set content rating: G, PG, T, MA. |
setTagForChildDirectedTreatment(int) |
COPPA compliance (TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE). |
setTagForUnderAgeOfConsent(int) |
GDPR compliance (TAG_FOR_UNDER_AGE_OF_CONSENT_TRUE). |
addTestDeviceId(String) |
Add a specific physical device for test ads. |
setHouseAdsEnabled(boolean) |
Globally enable or disable internal promotions. |
// Just pass the activity and a FrameLayout container
SmartAds.getInstance().showBannerAd(activity, container, new BannerAdListener() {
@Override public void onAdLoaded(View adView) {}
@Override public void onAdFailed(String error) {}
});// Preload once (ideally in onCreate or after previous ad)
SmartAds.getInstance().loadInterstitialAd(context);
// Show when the user completes an action
if (SmartAds.getInstance().isInterstitialAdAvailable()) {
SmartAds.getInstance().showInterstitialAd(activity, new InterstitialAdListener() {
@Override public void onAdDismissed() {
// Proceed to the next screen
}
});
}SmartAds.getInstance().showRewardedAd(activity, new RewardedAdListener() {
@Override public void onUserEarnedReward() {
// π Grant the reward!
}
});// Standard Template (MEDIUM, SMALL, or LARGE)
SmartAds.getInstance().showNativeAd(activity, container, NativeAdSize.MEDIUM, null);
// Custom XML Layout (Must be a NativeAdView in your XML)
SmartAds.getInstance().showNativeAd(activity, container, R.layout.my_layout, null);void onNextButtonClicked() {
if (SmartAds.getInstance().isInterstitialAdAvailable()) {
SmartAds.getInstance().showInterstitialAd(this, new InterstitialAdListener() {
@Override
public void onAdDismissed() {
startNextActivity();
}
});
} else {
startNextActivity();
}
}Add your own app promotions to show when network ads are unavailable or for direct marketing.
.addHouseAd(new HouseAd.Builder()
.setId("banner_house")
.setTitle("Try Our New App!")
.setDescription("Download now for free.")
.setClickUrl("GP_LINK")
.setIconResId(R.drawable.icon)
.setImageResId(R.drawable.banner)
.setRating(5.0f)
.build())
.setHouseAdsEnabled(true)Track revenue with precision by hooking into the analytics listener.
SmartAds.getInstance().setAnalyticsListener((adUnitId, adFormat, adNetwork, valueMicros, currencyCode, precision, extras) -> {
// Send data to Firebase, AppsFlyer, etc.
// revenue = valueMicros / 1000000.0;
});Important
SmartAds library does NOT include any mediation adapters by default. Only add the networks you actually use in AdMob mediation to keep your app size minimal.
Add mediation dependencies to your app's build.gradle ONLY if:
- β You have configured that network in your AdMob account mediation settings
- β You want to use that network for ad fill
- β Don't add them "just in case" - each adapter adds 3-5 MB to your app size
Always check the Google Mediation Page for the latest adapter versions.
Step 1: Add dependency to your app's build.gradle
dependencies {
implementation 'com.google.ads.mediation:facebook:6.21.0.0'
}Step 2: Enable in SmartAds config
SmartAdsConfig config = new SmartAdsConfig.Builder()
.setFacebookMediationEnabled(true) // Enable verification
// ... other config
.build();Manifest: No extra meta-data required.
Step 1: Add dependency to your app's build.gradle
dependencies {
implementation 'com.google.ads.mediation:applovin:13.5.1.0'
}Step 2: Add SDK key to AndroidManifest.xml (inside <application> tag)
<meta-data
android:name="applovin.sdk.key"
android:value="YOUR_APPLOVIN_SDK_KEY"/>Step 3: Enable in SmartAds config
SmartAdsConfig config = new SmartAdsConfig.Builder()
.setAppLovinMediationEnabled(true) // Enable verification
// ... other config
.build();Step 1: Add dependency to your app's build.gradle
dependencies {
implementation 'com.google.ads.mediation:unity:4.16.5.0'
}Step 2: Enable in SmartAds config
SmartAdsConfig config = new SmartAdsConfig.Builder()
.setUnityMediationEnabled(true) // Enable verification
// ... other config
.build();Manifest: No extra meta-data required. Configuration is handled via AdMob UI.
If you use minifyEnabled true, add these rules to your app's proguard-rules.pro only for the networks you're using:
# Google Mobile Ads (Always required)
-keep public class com.google.android.gms.ads.** { *; }
# Meta (Facebook) - Only if using Facebook mediation
-keep class com.facebook.ads.** { *; }
-dontwarn com.facebook.ads.**
# AppLovin - Only if using AppLovin mediation
-keep class com.applovin.** { *; }
-dontwarn com.applovin.**
# Unity Ads - Only if using Unity mediation
-keep class com.unity3d.ads.** { *; }
-keep class com.unity3d.services.** { *; }
-dontwarn com.unity3d.ads.**
-dontwarn com.unity3d.services.**
SmartAds provides built-in tools to ensure your mediation setup is working correctly:
Automatically logs which adapters are found during initialization (when logging is enabled):
SmartAdsConfig config = new SmartAdsConfig.Builder()
.setLoggingEnabled(true) // Enable to see adapter detection logs
.setFacebookMediationEnabled(true)
.setAppLovinMediationEnabled(true)
.build();
// Logs will show:
// β
Facebook / Meta Audience Network Adapter found.
// β
AppLovin Adapter found.
// β Unity Ads Adapter NOT found. Add dependency.You can also manually verify at any time:
SmartAds.getInstance().verifyMediation(activity);Launch the official AdMob inspector to see real-time ad fill status and mediation waterfall:
SmartAds.getInstance().launchAdInspector(activity);For comprehensive mediation testing, add the test suite to your app (debug builds only):
dependencies {
debugImplementation 'com.google.android.ads:mediation-test-suite:3.0.0'
}Then launch it:
SmartAds.getInstance().openMediationTestSuite(activity);Scenario: You only want to use Facebook and AppLovin mediation.
App's build.gradle:
dependencies {
implementation 'com.github.partharoypc:SmartAds:5.3.0'
// Only the networks you use
implementation 'com.google.ads.mediation:facebook:6.21.0.0'
implementation 'com.google.ads.mediation:applovin:13.5.1.0'
// Optional: Test suite for debugging
debugImplementation 'com.google.android.ads:mediation-test-suite:3.0.0'
}AndroidManifest.xml:
<application>
<!-- AdMob App ID (Required) -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
<!-- AppLovin SDK Key (Required for AppLovin) -->
<meta-data
android:name="applovin.sdk.key"
android:value="YOUR_APPLOVIN_SDK_KEY"/>
</application>Application class:
SmartAdsConfig config = new SmartAdsConfig.Builder()
.setAdsEnabled(true)
.setTestModeEnabled(BuildConfig.DEBUG)
.setLoggingEnabled(BuildConfig.DEBUG)
// Enable only the networks you added
.setFacebookMediationEnabled(true)
.setAppLovinMediationEnabled(true)
.setUnityMediationEnabled(false) // Not using Unity
// Your ad unit IDs
.setAdMobBannerId("ca-app-pub-xxx/banner")
.setAdMobInterstitialId("ca-app-pub-xxx/interstitial")
.build();
SmartAds.initialize(this, config);initialize(Application, SmartAdsConfig): Setup the SDK (Call once).getInstance(): Access the singleton instance.isInitialized(): Static check for initialization status.getVersion(): Returns "5.0.0".shutdown(): Fully stop all ad services and clear memory.
setAdsEnabled(boolean): Enable/Disable ads dynamically at runtime.areAdsEnabled(): Check current global ad status.updateConfig(SmartAdsConfig): Switch ad unit IDs or logic on the fly.preloadAds(Context): Manually trigger pre-fetching for all formats.isAnyAdShowing(): Returns true if any full-screen ad is active.
isAppOpenAdAvailable(): Check if App Open is ready.isInterstitialAdAvailable(): Check if Interstitial is loaded.isRewardedAdAvailable(): Check if Rewarded is loaded.getAppOpenAdStatus(): ReturnsLOADED,LOADING,IDLE, etc.
isPrivacyOptionsRequired(): Check if GDPR/CCPA settings are needed.showPrivacyOptionsForm(Activity): Display the UMP settings form.
To avoid memory leaks, always clean up containers in your Activity's onDestroy().
@Override
protected void onDestroy() {
SmartAds.getInstance().destroyBannerIn(bannerContainer);
SmartAds.getInstance().clearNativeIn(nativeContainer);
super.onDestroy();
}Licensed under MIT License. Created by Partha Roy.
