admob_nextgen 0.1.0
admob_nextgen: ^0.1.0 copied to clipboard
A Flutter plugin for Android Google Mobile Ads Next-Gen SDK with consent, banners, fullscreen ads, preloaders, and customizable native templates.
admob_nextgen #
Flutter plugin for the Android Google Mobile Ads Next-Gen SDK.
admob_nextgen provides Android-only wrappers for initialization, UMP consent,
banner ads, interstitial ads, rewarded ads, rewarded interstitial ads, app open
ads, preloaders, and customizable native ad templates.
Platform note: this package targets Android only. iOS is not implemented yet.
This is an unofficial Flutter plugin. It is not published, endorsed, or maintained by Google.
Preview #
| Banner placement | Native ad templates |
|---|---|
![]() |
![]() |
Known SDK issue #
Google's GMA Next-Gen SDK release notes say version 1.1.1 fixes an issue
where rewarded ad pods could freeze during transitions and prevent users from
closing the ad:
https://developers.google.com/admob/android/next-gen/rel-notes
There is also a public AdMob Community thread with a reported Next-Gen SDK
NullPointerException crash and stack trace:
Until that native SDK crash situation is clear, this package is not bumping the
bundled ads-mobile-sdk dependency to 1.1.1.
Features #
- Google Mobile Ads Next-Gen SDK initialization.
- UMP consent flow helpers.
- Banner ads with anchored, large anchored, and inline adaptive sizes.
- Interstitial, rewarded, rewarded interstitial, and app open ads.
- Interstitial and rewarded interstitial preloaders.
- Standard native ads with three prebuilt Android templates:
NativeBannerAdViewNativeSmallAdViewNativeLargeAdView
- Native ad styling for card color, CTA button, title, description, and ad badge.
Installation #
Add the package to pubspec.yaml:
dependencies:
admob_nextgen: ^0.1.0
Then run:
flutter pub get
Android setup #
Add your AdMob app ID to android/app/src/main/AndroidManifest.xml inside the
<application> tag:
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" />
The example test app ID is:
ca-app-pub-3940256099942544~3347511713
Use AdMob test ad unit IDs while developing. Do not use live ad units for local testing.
Mediation compatibility #
Do not use this package together with Google Mobile Ads mediation adapters such as Meta/Facebook Audience Network mediation. The Google Mobile Ads Next-Gen SDK is not currently compatible with existing mediation adapters, and adding a mediation dependency can produce duplicate Google Play services / GMS class errors at build time. Remove the mediation adapter dependency and use direct Next-Gen SDK ad units with this package.
Initialize ads and consent #
Important: unlike the old Google Mobile Ads Flutter SDK flow, this package
requires the Google Mobile Ads Next-Gen SDK to be initialized before loading or
showing ads. Call MobileAds.initialize() after consent allows ad requests.
import 'package:admob_nextgen/admob_nextgen.dart';
import 'package:flutter/widgets.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
try {
await ConsentInformation.instance.requestConsentInfoUpdate(
const ConsentRequestParameters(),
);
final formError = await ConsentForm.loadAndShowConsentFormIfRequired();
if (formError != null) {
print('Consent form failed: $formError');
}
if (await ConsentInformation.instance.canRequestAds()) {
await MobileAds.initialize();
}
} on ConsentFormException catch (error) {
print('Consent flow failed: ${error.error}');
} catch (error) {
print('Consent flow failed: $error');
}
runApp(const MyApp());
}
Warning: wrap the splash/startup consent flow in try/catch. If the device is
offline and requestConsentInfoUpdate() or
loadAndShowConsentFormIfRequired() fails, an uncaught exception can prevent
your splash flow from completing and leave the app stuck on the splash screen.
Catch ConsentFormException and any unexpected startup error, log or report
the failure, and continue to runApp() with your app's fallback state.
Optionally configure test devices:
await MobileAds.setRequestConfiguration(
const RequestConfiguration(
testDeviceIds: ['YOUR_TEST_DEVICE_ID'],
),
);
Banner ad #
BannerAdView(
adUnitId: 'ca-app-pub-3940256099942544/9214589741',
size: const AdSize.largeAnchored(),
height: 120,
)
Available banner sizes:
AdSize.anchored()AdSize.largeAnchored()AdSize.inline()
Interstitial ad #
final ad = await InterstitialAd.load(
adUnitId: 'ca-app-pub-3940256099942544/1033173712',
);
ad.listener = InterstitialAdListener(
onAdDismissedFullScreenContent: () {
print('Interstitial dismissed');
},
);
await ad.show();
Rewarded ad #
final ad = await RewardedAd.load(
adUnitId: 'ca-app-pub-3940256099942544/5224354917',
);
await ad.show(
onUserEarnedReward: (reward) {
print('Reward: ${reward.amount} ${reward.type}');
},
);
Rewarded interstitial ad #
final ad = await RewardedInterstitialAd.load(
adUnitId: 'ca-app-pub-3940256099942544/5354046379',
);
await ad.show(
onUserEarnedReward: (reward) {
print('Reward: ${reward.amount} ${reward.type}');
},
);
App open ad #
Load an app open ad, then show it when the app returns to the foreground:
AppOpenAd? appOpenAd;
StreamSubscription<AppState>? appStateSubscription;
Future<void> startAppOpenAds() async {
await AppStateEventNotifier.startListening();
appStateSubscription = AppStateEventNotifier.appStateStream.listen((state) {
if (state == AppState.foreground) {
showAppOpenAdIfAvailable();
}
});
}
Future<void> loadAppOpenAd() async {
appOpenAd = await AppOpenAd.load(
adUnitId: 'ca-app-pub-3940256099942544/9257395921',
);
}
Future<void> showAppOpenAdIfAvailable() async {
final ad = appOpenAd;
if (ad == null || !await ad.isAvailable()) return;
appOpenAd = null;
await ad.show();
}
Future<void> stopAppOpenAds() async {
await appStateSubscription?.cancel();
await AppStateEventNotifier.stopListening();
}
AppStateEventNotifier uses the Android process lifecycle, so opening and
closing a full-screen ad is not mistaken for leaving and returning to the app.
Native ads #
Load one NativeAd, then render it with one of the three prebuilt templates.
Native ads should be disposed when the placement is no longer used.
final nativeAd = NativeAd(
adUnitId: 'ca-app-pub-3940256099942544/2247696110',
);
await nativeAd.load();
Native banner template #
Smallest template with icon, title, and CTA button.
NativeBannerAdView(
nativeAd: nativeAd,
)
Native small template #
Compact template with icon, title, description, and CTA button.
NativeSmallAdView(
nativeAd: nativeAd,
)
Native large template #
Large template with icon, title, description, media content, and CTA button.
NativeLargeAdView(
nativeAd: nativeAd,
height: 380,
)
If you increase the CTA button height, also increase the native view height:
NativeLargeAdView(
nativeAd: nativeAd,
height: 430,
style: const NativeAdViewStyle(
callToActionHeight: 70,
),
)
Native customization options #
All styling options are optional:
NativeLargeAdView(
nativeAd: nativeAd,
height: 430,
style: const NativeAdViewStyle(
cardColor: Colors.white,
titleColor: Color(0xFF101828),
descriptionColor: Color(0xFF475467),
callToActionText: 'Install',
callToActionColor: Color(0xFF1E93E8),
callToActionTextColor: Colors.white,
callToActionHeight: 50,
callToActionCornerRadius: 14,
adBadgeText: 'Sponsored',
adBadgeTextColor: Color(0xFF1E93E8),
adBadgeColor: Colors.white,
adBadgeBorderColor: Color(0xFF1E93E8),
adBadgeBorderWidth: 1,
adBadgeCornerRadius: 6,
),
)
Supported NativeAdViewStyle fields:
cardColortitleColordescriptionColorcallToActionTextcallToActionColorcallToActionTextColorcallToActionHeightcallToActionCornerRadiusadBadgeTextadBadgeTextColoradBadgeColoradBadgeBorderColoradBadgeBorderWidthadBadgeCornerRadius
Preloaders #
Interstitial and rewarded interstitial ads can be preloaded:
await InterstitialAdPreloader.start(
adUnitId: 'ca-app-pub-3940256099942544/1033173712',
bufferSize: 2,
);
final ad = await InterstitialAdPreloader.poll(
adUnitId: 'ca-app-pub-3940256099942544/1033173712',
);
await ad?.show();
Request targeting #
Pass optional request hints to supported ad loads:
const request = AdRequest(
keywords: ['games', 'flutter'],
contentUrl: 'https://example.com/article',
customTargeting: {
'placement': ['home'],
},
);
final ad = await InterstitialAd.load(
adUnitId: 'ca-app-pub-3940256099942544/1033173712',
request: request,
);
Migrating from google_mobile_ads #
Replace the package import:
import 'package:admob_nextgen/admob_nextgen.dart';
AppState, AppStateEventNotifier.startListening(), stopListening(), and
appStateStream keep the same usage pattern as google_mobile_ads.
App open and interstitial loading is Future-first. Replace Google load
callbacks with await and try/catch:
try {
final ad = await InterstitialAd.load(adUnitId: interstitialAdUnitId);
ad.listener = InterstitialAdListener(
onAdDismissedFullScreenContent: createInterstitialAd,
onAdFailedToShowFullScreenContent: (_) => createInterstitialAd(),
);
await ad.show();
} on AdLoadException catch (error) {
print('Interstitial load failed: ${error.error}');
}
For app open ads, use the same pattern with AppOpenAd.load() and
AppOpenAdListener. Replace fullScreenContentCallback with listener.
Dismissed and failed-to-show ads are consumed and released automatically, so
do not call dispose() from terminal full-screen callbacks. Explicitly call
dispose() only when abandoning a loaded ad before showing it.
Native ads and banners use this package's template/widget APIs and are not
drop-in replacements for the old AdWidget, custom native factories, or
BannerAd constructor.


