From 382949737de80681f7744ecdbddf480713fd5e55 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 02:36:53 +0000 Subject: [PATCH] Implement real interstitial ad loading in Android app. - Add `play-services-ads:23.0.0` dependency to `android/app/build.gradle`. - Add AdMob App ID to `android/app/src/main/AndroidManifest.xml`. - Implement `loadInterstitial` and `showInterstitial` in `AdManager.kt` using Google Mobile Ads SDK. - Fix state management logic to prevent ad reuse and handle preloading. Co-authored-by: singhaditya21 <53948039+singhaditya21@users.noreply.github.com> --- android/app/build.gradle | 3 + android/app/src/main/AndroidManifest.xml | 5 + .../kotlin/com/climaai/app/ads/AdManager.kt | 91 ++++++++++++------- 3 files changed, 67 insertions(+), 32 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4fb7c06..2675914 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -130,4 +130,7 @@ dependencies { androidTestImplementation 'androidx.compose.ui:ui-test-junit4' debugImplementation 'androidx.compose.ui:ui-tooling' debugImplementation 'androidx.compose.ui:ui-test-manifest' + + // Google Mobile Ads + implementation 'com.google.android.gms:play-services-ads:23.0.0' } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1cd7fd5..5e5fe4e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -23,6 +23,11 @@ android:networkSecurityConfig="@xml/network_security_config" android:usesCleartextTraffic="false"> + + + = _adsEnabled.asStateFlow() + private var interstitialAd: InterstitialAd? = null + /** * Initialize the Mobile Ads SDK. * Call this in Application.onCreate() */ fun initialize(context: Context) { - // In production: - // MobileAds.initialize(context) { initializationStatus -> - // _isInitialized.value = true - // Log.d(TAG, "AdMob initialized") - // } - - // Mock initialization - _isInitialized.value = true - Log.d(TAG, "AdManager initialized (mock)") + MobileAds.initialize(context) { initializationStatus -> + _isInitialized.value = true + Log.d(TAG, "AdMob initialized") + } } /** @@ -67,30 +66,58 @@ object AdManager { * Load an interstitial ad. */ fun loadInterstitial(context: Context, onLoaded: () -> Unit, onFailed: (String) -> Unit) { - // In production: - // InterstitialAd.load(context, INTERSTITIAL_AD_UNIT_ID, AdRequest.Builder().build(), - // object : InterstitialAdLoadCallback() { - // override fun onAdLoaded(ad: InterstitialAd) { ... } - // override fun onAdFailedToLoad(error: LoadAdError) { ... } - // } - // ) - - // Mock: always succeed - onLoaded() + if (!_adsEnabled.value) { + onFailed("Ads are disabled") + return + } + + val adRequest = AdRequest.Builder().build() + InterstitialAd.load(context, INTERSTITIAL_AD_UNIT_ID, adRequest, + object : InterstitialAdLoadCallback() { + override fun onAdLoaded(ad: InterstitialAd) { + Log.d(TAG, "Ad was loaded.") + interstitialAd = ad + onLoaded() + } + + override fun onAdFailedToLoad(error: LoadAdError) { + Log.d(TAG, "Ad failed to load: ${error.message}") + interstitialAd = null + onFailed(error.message) + } + } + ) } /** * Show the interstitial ad. */ fun showInterstitial(activity: Activity, onDismissed: () -> Unit) { - // In production: - // interstitialAd?.show(activity) - // interstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() { - // override fun onAdDismissedFullScreenContent() { onDismissed() } - // } - - // Mock: immediately dismiss - onDismissed() + val ad = interstitialAd + if (ad != null) { + // Clear reference to avoid reuse and allow loading next ad + interstitialAd = null + + ad.fullScreenContentCallback = object : FullScreenContentCallback() { + override fun onAdDismissedFullScreenContent() { + Log.d(TAG, "Ad was dismissed.") + onDismissed() + } + + override fun onAdFailedToShowFullScreenContent(adError: AdError) { + Log.d(TAG, "Ad failed to show: ${adError.message}") + onDismissed() + } + + override fun onAdShowedFullScreenContent() { + Log.d(TAG, "Ad showed fullscreen content.") + } + } + ad.show(activity) + } else { + Log.d(TAG, "The interstitial ad wasn't ready yet.") + onDismissed() + } } }