diff --git a/samples/admob/banner_example/ios/Flutter/AppFrameworkInfo.plist b/samples/admob/banner_example/ios/Flutter/AppFrameworkInfo.plist
index 9625e105d..7c5696400 100644
--- a/samples/admob/banner_example/ios/Flutter/AppFrameworkInfo.plist
+++ b/samples/admob/banner_example/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 11.0
+ 12.0
diff --git a/samples/admob/banner_example/ios/Runner.xcodeproj/project.pbxproj b/samples/admob/banner_example/ios/Runner.xcodeproj/project.pbxproj
index d9c210628..1917bf7db 100644
--- a/samples/admob/banner_example/ios/Runner.xcodeproj/project.pbxproj
+++ b/samples/admob/banner_example/ios/Runner.xcodeproj/project.pbxproj
@@ -8,12 +8,12 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
- 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -42,6 +42,8 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
@@ -53,8 +55,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
- 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -68,6 +68,14 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 331C8082294A63A400263BE5 /* RunnerTests */ = {
+ isa = PBXGroup;
+ children = (
+ 331C807B294A618700263BE5 /* RunnerTests.swift */,
+ );
+ path = RunnerTests;
+ sourceTree = "";
+ };
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@@ -79,14 +87,6 @@
name = Flutter;
sourceTree = "";
};
- 331C8082294A63A400263BE5 /* RunnerTests */ = {
- isa = PBXGroup;
- children = (
- 331C807B294A618700263BE5 /* RunnerTests.swift */,
- );
- path = RunnerTests;
- sourceTree = "";
- };
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
@@ -129,7 +129,6 @@
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
331C807D294A63A400263BE5 /* Sources */,
- 331C807E294A63A400263BE5 /* Frameworks */,
331C807F294A63A400263BE5 /* Resources */,
);
buildRules = (
@@ -363,6 +362,7 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -377,7 +377,6 @@
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -395,7 +394,6 @@
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -411,7 +409,6 @@
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -541,6 +538,7 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -563,6 +561,7 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
diff --git a/samples/admob/banner_example/lib/app_bar_item.dart b/samples/admob/banner_example/lib/app_bar_item.dart
new file mode 100644
index 000000000..e77175cee
--- /dev/null
+++ b/samples/admob/banner_example/lib/app_bar_item.dart
@@ -0,0 +1,9 @@
+class AppBarItem {
+ static const adInpsectorText = 'Ad Inspector';
+ static const privacySettingsText = 'Privacy Settings';
+
+ final String label;
+ final int value;
+
+ AppBarItem(this.label, this.value);
+}
diff --git a/samples/admob/banner_example/lib/main.dart b/samples/admob/banner_example/lib/main.dart
index 3b28efa10..845f0c3cc 100644
--- a/samples/admob/banner_example/lib/main.dart
+++ b/samples/admob/banner_example/lib/main.dart
@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
+import 'app_bar_item.dart';
import 'consent_manager.dart';
void main() {
@@ -12,7 +13,7 @@ void main() {
));
}
-/// A simple app that loads a banner ad.
+/// An example app that loads a banner ad.
class BannerExample extends StatefulWidget {
const BannerExample({super.key});
@@ -21,10 +22,9 @@ class BannerExample extends StatefulWidget {
}
class BannerExampleState extends State {
- static const privacySettingsText = 'Privacy Settings';
-
final _consentManager = ConsentManager();
var _isMobileAdsInitializeCalled = false;
+ var _isPrivacyOptionsRequired = false;
BannerAd? _bannerAd;
bool _isLoaded = false;
Orientation? _currentOrientation;
@@ -44,6 +44,9 @@ class BannerExampleState extends State {
"${consentGatheringError.errorCode}: ${consentGatheringError.message}");
}
+ // Check if a privacy options entry point is required.
+ _getIsPrivacyOptionsRequired();
+
// Attempt to initialize the Mobile Ads SDK.
_initializeMobileAdsSDK();
});
@@ -58,10 +61,7 @@ class BannerExampleState extends State {
title: 'Banner Example',
home: Scaffold(
appBar: AppBar(
- title: const Text('Banner Example'),
- actions: _isMobileAdsInitializeCalled
- ? _privacySettingsAppBarAction()
- : null),
+ title: const Text('Banner Example'), actions: _appBarActions()),
body: OrientationBuilder(
builder: (context, orientation) {
if (_currentOrientation != orientation) {
@@ -88,33 +88,36 @@ class BannerExampleState extends State {
)));
}
- List _privacySettingsAppBarAction() {
+ List _appBarActions() {
+ var array = [AppBarItem(AppBarItem.adInpsectorText, 0)];
+
+ if (_isPrivacyOptionsRequired) {
+ array.add(AppBarItem(AppBarItem.privacySettingsText, 1));
+ }
+
return [
- // Regenerate the options menu to include a privacy setting.
- FutureBuilder(
- future: _consentManager.isPrivacyOptionsRequired(),
- builder: (context, snapshot) {
- final bool visibility = snapshot.data ?? false;
- return Visibility(
- visible: visibility,
- child: PopupMenuButton(
- onSelected: (String result) {
- if (result == privacySettingsText) {
- _consentManager.showPrivacyOptionsForm((formError) {
- if (formError != null) {
- debugPrint(
- "${formError.errorCode}: ${formError.message}");
- }
- });
- }
- },
- itemBuilder: (BuildContext context) =>
- >[
- const PopupMenuItem(
- value: privacySettingsText,
- child: Text(privacySettingsText))
- ],
- ));
+ PopupMenuButton(
+ itemBuilder: (context) => array
+ .map((item) => PopupMenuItem(
+ value: item,
+ child: Text(
+ item.label,
+ ),
+ ))
+ .toList(),
+ onSelected: (item) {
+ switch (item.value) {
+ case 0:
+ MobileAds.instance.openAdInspector((error) {
+ // Error will be non-null if ad inspector closed due to an error.
+ });
+ case 1:
+ _consentManager.showPrivacyOptionsForm((formError) {
+ if (formError != null) {
+ debugPrint("${formError.errorCode}: ${formError.message}");
+ }
+ });
+ }
})
];
}
@@ -169,6 +172,15 @@ class BannerExampleState extends State {
).load();
}
+ /// Redraw the app bar actions if a privacy options entry point is required.
+ void _getIsPrivacyOptionsRequired() async {
+ if (await _consentManager.isPrivacyOptionsRequired()) {
+ setState(() {
+ _isPrivacyOptionsRequired = true;
+ });
+ }
+ }
+
/// Initialize the Mobile Ads SDK if the SDK has gathered consent aligned with
/// the app's configured messages.
void _initializeMobileAdsSDK() async {
@@ -176,14 +188,12 @@ class BannerExampleState extends State {
return;
}
- var canRequestAds = await _consentManager.canRequestAds();
- if (canRequestAds) {
- setState(() {
- _isMobileAdsInitializeCalled = true;
- });
+ if (await _consentManager.canRequestAds()) {
+ _isMobileAdsInitializeCalled = true;
// Initialize the Mobile Ads SDK.
MobileAds.instance.initialize();
+
// Load an ad.
_loadAd();
}