diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 774e04e24..e630c0264 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -29,7 +29,7 @@ jobs:
- "samples/admob/rewarded_example"
- "samples/admob/rewarded_interstitial_example"
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
@@ -60,11 +60,11 @@ jobs:
- "samples/admob/rewarded_example"
- "samples/admob/rewarded_interstitial_example"
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Select Xcode version
- run: sudo xcode-select -s '/Applications/Xcode_16.3.0.app/Contents/Developer'
+ run: sudo xcode-select -s '/Applications/Xcode_26.2.app/Contents/Developer'
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh stable
- name: "Install Tools"
@@ -94,7 +94,7 @@ jobs:
- "samples/admob/rewarded_example"
- "samples/admob/rewarded_interstitial_example"
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/cancel.yaml b/.github/workflows/cancel.yaml
index c0f41e7af..b41ac8c8f 100644
--- a/.github/workflows/cancel.yaml
+++ b/.github/workflows/cancel.yaml
@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 3
steps:
- - uses: styfle/cancel-workflow-action@0.12.1
+ - uses: styfle/cancel-workflow-action@0.13.1
with:
workflow_id: 5958127
access_token: ${{ github.token }}
diff --git a/.github/workflows/gma_mediation_applovin.yaml b/.github/workflows/gma_mediation_applovin.yaml
index 8d648f831..ff1e55c1c 100644
--- a/.github/workflows/gma_mediation_applovin.yaml
+++ b/.github/workflows/gma_mediation_applovin.yaml
@@ -31,10 +31,10 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- - uses: actions/setup-java@v4
+ - uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
@@ -56,11 +56,11 @@ jobs:
- uses: swift-actions/setup-swift@v2
with:
swift-version: "5.7.2"
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Select Xcode version
- run: sudo xcode-select -s '/Applications/Xcode_16.2.0.app/Contents/Developer'
+ run: sudo xcode-select -s '/Applications/Xcode_26.2.app/Contents/Developer'
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh stable
- name: "Install Tools"
@@ -73,8 +73,8 @@ jobs:
flutter pub get
flutter precache --ios
pod install --repo-update
- xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' test
- - uses: actions/upload-artifact@v4
+ xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test
+ - uses: actions/upload-artifact@v7
if: failure()
with:
name: iOSTestResults
@@ -84,7 +84,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_chartboost.yaml b/.github/workflows/gma_mediation_chartboost.yaml
index 4589ecf6b..b8f93d1dc 100644
--- a/.github/workflows/gma_mediation_chartboost.yaml
+++ b/.github/workflows/gma_mediation_chartboost.yaml
@@ -31,7 +31,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_dtexchange.yaml b/.github/workflows/gma_mediation_dtexchange.yaml
index 8a2dbe17e..756bcb263 100644
--- a/.github/workflows/gma_mediation_dtexchange.yaml
+++ b/.github/workflows/gma_mediation_dtexchange.yaml
@@ -31,10 +31,10 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- - uses: actions/setup-java@v4
+ - uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
@@ -56,11 +56,11 @@ jobs:
- uses: swift-actions/setup-swift@v2
with:
swift-version: "6.0.0"
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Select Xcode version
- run: sudo xcode-select -s '/Applications/Xcode_16.2.0.app/Contents/Developer'
+ run: sudo xcode-select -s '/Applications/Xcode_26.2.app/Contents/Developer'
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh stable
- name: "Install Tools"
@@ -73,8 +73,8 @@ jobs:
flutter pub get
flutter precache --ios
pod install
- xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' test
- - uses: actions/upload-artifact@v4
+ xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test
+ - uses: actions/upload-artifact@v7
if: failure()
with:
name: iOSTestResults
@@ -84,7 +84,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_inmobi.yaml b/.github/workflows/gma_mediation_inmobi.yaml
index 944721f33..73163d762 100644
--- a/.github/workflows/gma_mediation_inmobi.yaml
+++ b/.github/workflows/gma_mediation_inmobi.yaml
@@ -31,7 +31,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_ironsource.yaml b/.github/workflows/gma_mediation_ironsource.yaml
index 5807d8cb8..d4032b306 100644
--- a/.github/workflows/gma_mediation_ironsource.yaml
+++ b/.github/workflows/gma_mediation_ironsource.yaml
@@ -31,10 +31,10 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- - uses: actions/setup-java@v4
+ - uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
@@ -55,11 +55,11 @@ jobs:
- uses: swift-actions/setup-swift@v2
with:
swift-version: "6.0.0"
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Select Xcode version
- run: sudo xcode-select -s '/Applications/Xcode_16.2.0.app/Contents/Developer'
+ run: sudo xcode-select -s '/Applications/Xcode_26.2.app/Contents/Developer'
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh stable
- name: "Install Tools"
@@ -72,8 +72,8 @@ jobs:
flutter pub get
flutter precache --ios
pod install
- xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' test
- - uses: actions/upload-artifact@v4
+ xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test
+ - uses: actions/upload-artifact@v7
if: failure()
with:
name: iOSTestResults
@@ -83,7 +83,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_liftoffmonetize.yaml b/.github/workflows/gma_mediation_liftoffmonetize.yaml
index 6a20ad0b1..43e9ed086 100644
--- a/.github/workflows/gma_mediation_liftoffmonetize.yaml
+++ b/.github/workflows/gma_mediation_liftoffmonetize.yaml
@@ -31,10 +31,10 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- - uses: actions/setup-java@v4
+ - uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
@@ -56,11 +56,11 @@ jobs:
- uses: swift-actions/setup-swift@v2
with:
swift-version: "5.7.2"
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Select Xcode version
- run: sudo xcode-select -s '/Applications/Xcode_16.2.0.app/Contents/Developer'
+ run: sudo xcode-select -s '/Applications/Xcode_26.2.app/Contents/Developer'
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh stable
- name: "Install Tools"
@@ -73,8 +73,8 @@ jobs:
flutter pub get
flutter precache --ios
pod install
- xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' test
- - uses: actions/upload-artifact@v4
+ xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test
+ - uses: actions/upload-artifact@v7
if: failure()
with:
name: iOSTestResults
@@ -85,7 +85,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_meta.yaml b/.github/workflows/gma_mediation_meta.yaml
index ff7134bd3..95eb6933e 100644
--- a/.github/workflows/gma_mediation_meta.yaml
+++ b/.github/workflows/gma_mediation_meta.yaml
@@ -31,7 +31,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_mintegral.yaml b/.github/workflows/gma_mediation_mintegral.yaml
index bd9ff3e1d..332bb5b25 100644
--- a/.github/workflows/gma_mediation_mintegral.yaml
+++ b/.github/workflows/gma_mediation_mintegral.yaml
@@ -31,7 +31,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_pangle.yaml b/.github/workflows/gma_mediation_pangle.yaml
index d4b573ef8..cb2d4ce9e 100644
--- a/.github/workflows/gma_mediation_pangle.yaml
+++ b/.github/workflows/gma_mediation_pangle.yaml
@@ -31,7 +31,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/gma_mediation_unity.yaml b/.github/workflows/gma_mediation_unity.yaml
index e0fc3fffd..2e33056f6 100644
--- a/.github/workflows/gma_mediation_unity.yaml
+++ b/.github/workflows/gma_mediation_unity.yaml
@@ -31,10 +31,10 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- - uses: actions/setup-java@v4
+ - uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
@@ -56,11 +56,11 @@ jobs:
- uses: swift-actions/setup-swift@v2
with:
swift-version: "6.0.0"
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Select Xcode version
- run: sudo xcode-select -s '/Applications/Xcode_16.2.0.app/Contents/Developer'
+ run: sudo xcode-select -s '/Applications/Xcode_26.2.app/Contents/Developer'
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh stable
- name: "Install Tools"
@@ -73,8 +73,8 @@ jobs:
flutter pub get
flutter precache --ios
pod install
- xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' test
- - uses: actions/upload-artifact@v4
+ xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test
+ - uses: actions/upload-artifact@v7
if: failure()
with:
name: iOSTestResults
@@ -85,7 +85,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.github/workflows/google_mobile_ads.yaml b/.github/workflows/google_mobile_ads.yaml
index 9024b03cb..720747440 100644
--- a/.github/workflows/google_mobile_ads.yaml
+++ b/.github/workflows/google_mobile_ads.yaml
@@ -34,10 +34,10 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- - uses: actions/setup-java@v4
+ - uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
@@ -56,11 +56,14 @@ jobs:
runs-on: macos-latest
timeout-minutes: 40
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: swift-actions/setup-swift@v2
+ with:
+ swift-version: "6.0.0"
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Select Xcode version
- run: sudo xcode-select -s '/Applications/Xcode_16.3.0.app/Contents/Developer'
+ run: sudo xcode-select -s '/Applications/Xcode_26.2.app/Contents/Developer'
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh stable
- name: "Install Tools"
@@ -74,8 +77,8 @@ jobs:
flutter clean
flutter pub get
pod install
- xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.4' test
- - uses: actions/upload-artifact@v4
+ xcodebuild -configuration Debug -resultBundlePath TestResults VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2' test
+ - uses: actions/upload-artifact@v7
if: failure()
with:
name: iOSTestResults
@@ -85,7 +88,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: "Install Flutter"
diff --git a/.gitignore b/.gitignore
index 3cb9a0984..ac23f68c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,6 @@ Pods/
**/Flutter/flutter_assets/
ServiceDefinitions.json
xcuserdata/
-xcshareddata/
local.properties
keystore.properties
diff --git a/CODEOWNERS b/CODEOWNERS
index ad5d0447e..80db18083 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -4,5 +4,5 @@
# These names are just suggestions. It is fine to have your changes
# reviewed by someone else.
-packages/google_mobile_ads/* @bparrishMines @jjliu15 @luo86 @srichakradhar @LTPhantom
-.github/ @bparrishMines @jjliu15 @luo86 @srichakradhar @LTPhantom
+packages/google_mobile_ads/* @berile @luo86 @LTPhantom @thanvirm
+.github/ @berile @luo86 @LTPhantom @thanvirm
diff --git a/packages/google_mobile_ads/CHANGELOG.md b/packages/google_mobile_ads/CHANGELOG.md
index 699008229..e3c5b1910 100644
--- a/packages/google_mobile_ads/CHANGELOG.md
+++ b/packages/google_mobile_ads/CHANGELOG.md
@@ -1,3 +1,41 @@
+## 9.0.0
+* Resolves pending start/stop method channel futures in AppStateNotifier Android. [PR 1438](https://github.com/googleads/googleads-mobile-flutter/pull/1438)
+* Updates GMA Android SDK dependencies:
+ * [Google Mobile Ads](https://developers.google.com/admob/android/quick-start) SDK version `25.3.0`.
+ * [Google Mobile Ads Next-Gen](https://developers.google.com/admob/android/next-gen/rel-notes) SDK version `1.1.0`.
+* Updates GMA [iOS](https://developers.google.com/admob/ios/rel-notes) dependency to `13.3.0`.
+* Uses latest UMP SDK:
+ * [Android](https://developers.google.com/admob/android/privacy/release-notes) UMP SDK version 4.0.0.
+ * [iOS](https://developers.google.com/admob/ios/privacy/download#release_notes) UMP SDK version 3.1.0.
+
+## 8.0.0
+* Updates minimum Flutter SDK to 3.38.1
+* Updates Dart SDK low bound to 3.10.0.
+* Adds Swift Package Manager Support for the plugin. [PR 1395](https://github.com/googleads/googleads-mobile-flutter/pull/1395)
+* Adds `isCollapsible` API. [FR 1294](https://github.com/googleads/googleads-mobile-flutter/issues/1294)
+* Renamed method name to avoid possible name collision. [FR 1394](https://github.com/googleads/googleads-mobile-flutter/issues/1394)
+* Migrated to use UISceneDelegate protocol. [Issue 1391](https://github.com/googleads/googleads-mobile-flutter/issues/1391)
+* New to Anchored adaptive banner ads:
+ * The following APIs have been deprecated for their replacement:
+ * The `getCurrentOrientationAnchoredAdaptiveBannerAdSize` function is deprecated. Instead, use the `getLargeAnchoredAdaptiveBannerAdSize` function.
+ * The `getAnchoredAdaptiveBannerAdSize` function is deprecated. Instead, use the `getLargeAnchoredAdaptiveBannerAdSizeWithOrientation` function.
+* Updates GMA [Android](https://developers.google.com/admob/android/rel-notes) dependency to 25.1.0
+* Updates GMA [iOS](https://developers.google.com/admob/ios/rel-notes) dependency to 13.2.0
+* Uses latest UMP SDK:
+ * [Android](https://developers.google.com/admob/android/privacy/release-notes) UMP SDK version 4.0.0.
+ * [iOS](https://developers.google.com/admob/ios/privacy/download#release_notes) UMP SDK version 3.1.0.
+
+## 7.0.0
+* Added character limits expected for Native Ad Templates. Issues [1243](https://github.com/googleads/googleads-mobile-flutter/issues/1243) and [1332](https://github.com/googleads/googleads-mobile-flutter/issues/1332)
+* Fixed padding for Native Ads small template. [Issue 1357](https://github.com/googleads/googleads-mobile-flutter/issues/1357)
+* Updated to use Gradle plugin 9.2.1 [Issue 1361](https://github.com/googleads/googleads-mobile-flutter/issues/1361)
+* Updates dependencies. [Issue 1366](https://github.com/googleads/googleads-mobile-flutter/issues/1366)
+* Updates GMA [Android](https://developers.google.com/admob/android/rel-notes) dependency to 24.9.0
+* Updates GMA [iOS](https://developers.google.com/admob/ios/rel-notes) dependency to 12.14.0
+* Uses latest UMP SDK:
+ * [Android](https://developers.google.com/admob/android/privacy/release-notes) UMP SDK version 4.0.0.
+ * [iOS](https://developers.google.com/admob/ios/privacy/download#release_notes) UMP SDK version 3.1.0.
+
## 6.0.0
* Updates minimum Flutter SDK to 3.27.0
* Updates Dart SDK low bound to 3.6.0.
diff --git a/packages/google_mobile_ads/android/build.gradle b/packages/google_mobile_ads/android/build.gradle
index 948e368f3..b2be9dcac 100644
--- a/packages/google_mobile_ads/android/build.gradle
+++ b/packages/google_mobile_ads/android/build.gradle
@@ -1,14 +1,17 @@
group 'io.flutter.plugins.googlemobileads'
-version '6.0.0'
+version '9.0.0'
buildscript {
+ ext {
+ agp_version = '8.13.1'
+ }
repositories {
google()
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.3.2'
+ classpath "com.android.tools.build:gradle:$agp_version"
}
}
@@ -22,29 +25,60 @@ rootProject.allprojects {
apply plugin: 'com.android.library'
android {
- compileSdk 35
+ def dartEnvironmentVariables = []
+ if (project.hasProperty('dart-defines')) {
+ dartEnvironmentVariables = project.property('dart-defines')
+ .split(',')
+ .collectEntries { entry ->
+ def pair = new String(entry.decodeBase64(), 'UTF-8').split('=')
+ [(pair.first()): pair.last()]
+ }
+ }
+
+ def useNextGenSdk = dartEnvironmentVariables.USE_NEXT_GEN_SDK ? dartEnvironmentVariables.USE_NEXT_GEN_SDK : false
+
+ compileSdk 36
if (project.android.hasProperty('namespace')) {
namespace 'io.flutter.plugins.googlemobileads'
}
defaultConfig {
- minSdk 23
+ minSdk 24
}
lintOptions {
disable 'InvalidPackage'
}
+ sourceSets.named("main") {
+ java.srcDirs("src/main/java")
+ if (useNextGenSdk) {
+ java.srcDirs("src/adsNextGenSdk/java")
+ } else {
+ java.srcDirs("src/playServices/java")
+ }
+
+ res.srcDirs("src/main/res")
+ if (useNextGenSdk) {
+ res.srcDirs("src/adsNextGenSdk/res")
+ } else {
+ res.srcDirs("src/playServices/res")
+ }
+ }
dependencies {
- api 'com.google.android.gms:play-services-ads:24.1.0'
- implementation 'com.google.android.ump:user-messaging-platform:3.2.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
- implementation 'androidx.lifecycle:lifecycle-process:2.6.2'
- implementation 'com.google.errorprone:error_prone_annotations:2.16'
+ if (useNextGenSdk) {
+ api 'com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:1.1.1'
+ } else {
+ api 'com.google.android.gms:play-services-ads:25.3.0'
+ }
+ implementation 'com.google.android.ump:user-messaging-platform:4.0.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
+ implementation 'androidx.lifecycle:lifecycle-process:2.10.0'
+ implementation 'com.google.errorprone:error_prone_annotations:2.48.0'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.hamcrest:hamcrest:3.0'
- testImplementation 'org.mockito:mockito-core:5.15.2'
- testImplementation 'org.robolectric:robolectric:4.14.1'
- testImplementation 'androidx.test:core:1.5.0'
+ testImplementation 'org.mockito:mockito-core:5.23.0'
+ testImplementation 'org.robolectric:robolectric:4.16.1'
+ testImplementation 'androidx.test:core:1.7.0'
}
testOptions {
unitTests {
@@ -54,15 +88,11 @@ android {
}
afterEvaluate {
- def containsEmbeddingDependencies = false
- for (def configuration : configurations.all) {
- for (def dependency : configuration.dependencies) {
- if (dependency.group == 'io.flutter' &&
+ def containsEmbeddingDependencies = configurations.any { configuration ->
+ configuration.dependencies.any { dependency ->
+ dependency.group == 'io.flutter' &&
dependency.name.startsWith('flutter_embedding') &&
- dependency.isTransitive()) {
- containsEmbeddingDependencies = true
- break
- }
+ (dependency instanceof ModuleDependency && dependency.isTransitive())
}
}
if (!containsEmbeddingDependencies) {
diff --git a/packages/google_mobile_ads/android/gradle/gradle-daemon-jvm.properties b/packages/google_mobile_ads/android/gradle/gradle-daemon-jvm.properties
new file mode 100644
index 000000000..6c1139ec0
--- /dev/null
+++ b/packages/google_mobile_ads/android/gradle/gradle-daemon-jvm.properties
@@ -0,0 +1,12 @@
+#This file is generated by updateDaemonJvm
+toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
+toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
+toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
+toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
+toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73bcfb608d1fde9fb62e462f834a3299/redirect
+toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/846ee0d876d26a26f37aa1ce8de73224/redirect
+toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
+toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
+toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/9482ddec596298c84656d31d16652665/redirect
+toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/39701d92e1756bb2f141eb67cd4c660e/redirect
+toolchainVersion=21
diff --git a/packages/google_mobile_ads/android/gradle/wrapper/gradle-wrapper.properties b/packages/google_mobile_ads/android/gradle/wrapper/gradle-wrapper.properties
index 9c034ab11..c5856afbe 100644
--- a/packages/google_mobile_ads/android/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/google_mobile_ads/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat May 13 14:37:03 CEST 2023
+#Thu Dec 04 10:45:11 PST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/packages/google_mobile_ads/android/src/adsNextGenSdk/java/com/google/android/ads/nativetemplates/TemplateView.java b/packages/google_mobile_ads/android/src/adsNextGenSdk/java/com/google/android/ads/nativetemplates/TemplateView.java
new file mode 100644
index 000000000..1319a2d57
--- /dev/null
+++ b/packages/google_mobile_ads/android/src/adsNextGenSdk/java/com/google/android/ads/nativetemplates/TemplateView.java
@@ -0,0 +1,295 @@
+// Copyright 2026 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.android.ads.nativetemplates;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.RatingBar;
+import android.widget.TextView;
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import com.google.android.libraries.ads.mobile.sdk.common.Image;
+import com.google.android.libraries.ads.mobile.sdk.nativead.MediaView;
+import com.google.android.libraries.ads.mobile.sdk.nativead.NativeAd;
+import com.google.android.libraries.ads.mobile.sdk.nativead.NativeAdView;
+import io.flutter.plugins.googlemobileads.R;
+
+/** Base class for a template view. */
+public final class TemplateView extends FrameLayout {
+
+ private int templateType;
+ private NativeTemplateStyle styles;
+ private NativeAd nativeAd;
+ private NativeAdView nativeAdView;
+
+ private TextView primaryView;
+ private TextView secondaryView;
+ private RatingBar ratingBar;
+ private TextView tertiaryView;
+ private ImageView iconView;
+ private MediaView mediaView;
+ private Button callToActionView;
+ private ConstraintLayout background;
+
+ private static final String MEDIUM_TEMPLATE = "medium_template";
+ private static final String SMALL_TEMPLATE = "small_template";
+
+ public TemplateView(Context context) {
+ super(context);
+ }
+
+ public TemplateView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ initView(context, attrs);
+ }
+
+ public TemplateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView(context, attrs);
+ }
+
+ public TemplateView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ initView(context, attrs);
+ }
+
+ public void setStyles(NativeTemplateStyle styles) {
+ this.styles = styles;
+ this.applyStyles();
+ }
+
+ public NativeAdView getNativeAdView() {
+ return nativeAdView;
+ }
+
+ private void applyStyles() {
+
+ Drawable mainBackground = styles.getMainBackgroundColor();
+ if (mainBackground != null) {
+ background.setBackground(mainBackground);
+ if (primaryView != null) {
+ primaryView.setBackground(mainBackground);
+ }
+ if (secondaryView != null) {
+ secondaryView.setBackground(mainBackground);
+ }
+ if (tertiaryView != null) {
+ tertiaryView.setBackground(mainBackground);
+ }
+ }
+
+ Typeface primary = styles.getPrimaryTextTypeface();
+ if (primary != null && primaryView != null) {
+ primaryView.setTypeface(primary);
+ }
+
+ Typeface secondary = styles.getSecondaryTextTypeface();
+ if (secondary != null && secondaryView != null) {
+ secondaryView.setTypeface(secondary);
+ }
+
+ Typeface tertiary = styles.getTertiaryTextTypeface();
+ if (tertiary != null && tertiaryView != null) {
+ tertiaryView.setTypeface(tertiary);
+ }
+
+ Typeface ctaTypeface = styles.getCallToActionTextTypeface();
+ if (ctaTypeface != null && callToActionView != null) {
+ callToActionView.setTypeface(ctaTypeface);
+ }
+
+ if (styles.getPrimaryTextTypefaceColor() != null && primaryView != null) {
+ primaryView.setTextColor(styles.getPrimaryTextTypefaceColor());
+ }
+
+ if (styles.getSecondaryTextTypefaceColor() != null && secondaryView != null) {
+ secondaryView.setTextColor(styles.getSecondaryTextTypefaceColor());
+ }
+
+ if (styles.getTertiaryTextTypefaceColor() != null && tertiaryView != null) {
+ tertiaryView.setTextColor(styles.getTertiaryTextTypefaceColor());
+ }
+
+ if (styles.getCallToActionTypefaceColor() != null && callToActionView != null) {
+ callToActionView.setTextColor(styles.getCallToActionTypefaceColor());
+ }
+
+ float ctaTextSize = styles.getCallToActionTextSize();
+ if (ctaTextSize > 0 && callToActionView != null) {
+ callToActionView.setTextSize(ctaTextSize);
+ }
+
+ float primaryTextSize = styles.getPrimaryTextSize();
+ if (primaryTextSize > 0 && primaryView != null) {
+ primaryView.setTextSize(primaryTextSize);
+ }
+
+ float secondaryTextSize = styles.getSecondaryTextSize();
+ if (secondaryTextSize > 0 && secondaryView != null) {
+ secondaryView.setTextSize(secondaryTextSize);
+ }
+
+ float tertiaryTextSize = styles.getTertiaryTextSize();
+ if (tertiaryTextSize > 0 && tertiaryView != null) {
+ tertiaryView.setTextSize(tertiaryTextSize);
+ }
+
+ Drawable ctaBackground = styles.getCallToActionBackgroundColor();
+ if (ctaBackground != null && callToActionView != null) {
+ callToActionView.setBackground(ctaBackground);
+ }
+
+ Drawable primaryBackground = styles.getPrimaryTextBackgroundColor();
+ if (primaryBackground != null && primaryView != null) {
+ primaryView.setBackground(primaryBackground);
+ }
+
+ Drawable secondaryBackground = styles.getSecondaryTextBackgroundColor();
+ if (secondaryBackground != null && secondaryView != null) {
+ secondaryView.setBackground(secondaryBackground);
+ }
+
+ Drawable tertiaryBackground = styles.getTertiaryTextBackgroundColor();
+ if (tertiaryBackground != null && tertiaryView != null) {
+ tertiaryView.setBackground(tertiaryBackground);
+ }
+
+ invalidate();
+ requestLayout();
+ }
+
+ private boolean adHasOnlyStore(NativeAd nativeAd) {
+ String store = nativeAd.getStore();
+ String advertiser = nativeAd.getAdvertiser();
+ return !TextUtils.isEmpty(store) && TextUtils.isEmpty(advertiser);
+ }
+
+ public void setNativeAd(NativeAd nativeAd) {
+ this.nativeAd = nativeAd;
+
+ String store = nativeAd.getStore();
+ String advertiser = nativeAd.getAdvertiser();
+ String headline = nativeAd.getHeadline();
+ String body = nativeAd.getBody();
+ String cta = nativeAd.getCallToAction();
+ Double starRating = nativeAd.getStarRating();
+ Image icon = nativeAd.getIcon();
+
+ String secondaryText;
+
+ nativeAdView.setCallToActionView(callToActionView);
+ nativeAdView.setHeadlineView(primaryView);
+ secondaryView.setVisibility(VISIBLE);
+ if (adHasOnlyStore(nativeAd)) {
+ nativeAdView.setStoreView(secondaryView);
+ secondaryText = store;
+ } else if (!TextUtils.isEmpty(advertiser)) {
+ nativeAdView.setAdvertiserView(secondaryView);
+ secondaryText = advertiser;
+ } else {
+ secondaryText = "";
+ }
+
+ primaryView.setText(headline);
+ callToActionView.setText(cta);
+
+ // Set the secondary view to be the star rating if available.
+ if (starRating != null && starRating > 0) {
+ secondaryView.setVisibility(GONE);
+ ratingBar.setVisibility(VISIBLE);
+ ratingBar.setRating(starRating.floatValue());
+
+ nativeAdView.setStarRatingView(ratingBar);
+ } else {
+ secondaryView.setText(secondaryText);
+ secondaryView.setVisibility(VISIBLE);
+ ratingBar.setVisibility(GONE);
+ }
+
+ if (icon != null) {
+ iconView.setVisibility(VISIBLE);
+ iconView.setImageDrawable(icon.getDrawable());
+ } else {
+ iconView.setVisibility(GONE);
+ }
+
+ if (tertiaryView != null) {
+ tertiaryView.setText(body);
+ nativeAdView.setBodyView(tertiaryView);
+ }
+
+ nativeAdView.registerNativeAd(nativeAd, mediaView);
+ }
+
+ /**
+ * To prevent memory leaks, make sure to destroy your ad when you don't need it anymore. This
+ * method does not destroy the template view.
+ * https://developers.google.com/admob/android/native-unified#destroy_ad
+ */
+ public void destroyNativeAd() {
+ nativeAd.destroy();
+ }
+
+ public String getTemplateTypeName() {
+ if (templateType == R.layout.gnt_medium_template_view) {
+ return MEDIUM_TEMPLATE;
+ } else if (templateType == R.layout.gnt_small_template_view) {
+ return SMALL_TEMPLATE;
+ }
+ return "";
+ }
+
+ private void initView(Context context, AttributeSet attributeSet) {
+
+ TypedArray attributes =
+ context.getTheme().obtainStyledAttributes(attributeSet, R.styleable.TemplateView, 0, 0);
+
+ try {
+ templateType =
+ attributes.getResourceId(
+ R.styleable.TemplateView_gnt_template_type, R.layout.gnt_medium_template_view);
+ } finally {
+ attributes.recycle();
+ }
+ LayoutInflater inflater =
+ (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(templateType, this);
+ }
+
+ @Override
+ public void onFinishInflate() {
+ super.onFinishInflate();
+ nativeAdView = (NativeAdView) findViewById(R.id.native_ad_view);
+ primaryView = (TextView) findViewById(R.id.primary);
+ secondaryView = (TextView) findViewById(R.id.secondary);
+ tertiaryView = (TextView) findViewById(R.id.body);
+
+ ratingBar = (RatingBar) findViewById(R.id.rating_bar);
+ ratingBar.setEnabled(false);
+
+ callToActionView = (Button) findViewById(R.id.cta);
+ iconView = (ImageView) findViewById(R.id.icon);
+ mediaView = (MediaView) findViewById(R.id.media_view);
+ background = (ConstraintLayout) findViewById(R.id.background);
+ }
+}
diff --git a/packages/google_mobile_ads/android/src/adsNextGenSdk/java/io/flutter/plugins/googlemobileads/AdInstanceManager.java b/packages/google_mobile_ads/android/src/adsNextGenSdk/java/io/flutter/plugins/googlemobileads/AdInstanceManager.java
new file mode 100644
index 000000000..1a3c91834
--- /dev/null
+++ b/packages/google_mobile_ads/android/src/adsNextGenSdk/java/io/flutter/plugins/googlemobileads/AdInstanceManager.java
@@ -0,0 +1,272 @@
+// Copyright 2026 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package io.flutter.plugins.googlemobileads;
+
+import android.app.Activity;
+import android.os.Handler;
+import android.os.Looper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import com.google.android.gms.ads.AdError;
+import com.google.android.libraries.ads.mobile.sdk.common.ResponseInfo;
+import com.google.android.libraries.ads.mobile.sdk.common.AdValue;
+import com.google.android.libraries.ads.mobile.sdk.common.PrecisionType;
+import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugins.googlemobileads.FlutterAd.FlutterAdError;
+import io.flutter.plugins.googlemobileads.FlutterAd.FlutterResponseInfo;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Maintains reference to ad instances for the {@link
+ * io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin}.
+ *
+ *
When an Ad is loaded from Dart, an equivalent ad object is created and maintained here to
+ * provide access until the ad is disposed.
+ */
+class AdInstanceManager {
+ @Nullable private Activity activity;
+
+ @NonNull private final Map ads;
+ @NonNull private final MethodChannel channel;
+
+ static final String NEXT_GEN_DOMAIN = "com.google.android.libraries.ads.mobile.sdk";
+
+ /**
+ * Initializes the ad instance manager. We only need a method channel to start loading ads, but an
+ * activity must be present in order to attach any ads to the view hierarchy.
+ */
+ AdInstanceManager(@NonNull MethodChannel channel) {
+ this.channel = channel;
+ this.ads = new HashMap<>();
+ }
+
+ void setActivity(@Nullable Activity activity) {
+ this.activity = activity;
+ }
+
+ @Nullable
+ Activity getActivity() {
+ return activity;
+ }
+
+ @Nullable
+ FlutterAd adForId(int id) {
+ return ads.get(id);
+ }
+
+ @Nullable
+ Integer adIdFor(@NonNull FlutterAd ad) {
+ for (Integer adId : ads.keySet()) {
+ if (ads.get(adId) == ad) {
+ return adId;
+ }
+ }
+ return null;
+ }
+
+ void trackAd(@NonNull FlutterAd ad, int adId) {
+ if (ads.get(adId) != null) {
+ throw new IllegalArgumentException(
+ String.format("Ad for following adId already exists: %d", adId));
+ }
+ ads.put(adId, ad);
+ }
+
+ void disposeAd(int adId) {
+ if (!ads.containsKey(adId)) {
+ return;
+ }
+ FlutterAd ad = ads.get(adId);
+ if (ad != null) {
+ ad.dispose();
+ }
+ ads.remove(adId);
+ }
+
+ void disposeAllAds() {
+ for (Map.Entry entry : ads.entrySet()) {
+ if (entry.getValue() != null) {
+ entry.getValue().dispose();
+ }
+ }
+ ads.clear();
+ }
+
+ void onAdLoaded(int adId, @Nullable ResponseInfo responseInfo) {
+ Map