From 6da4b59b3a81e1bbf3285afb9dcd2e3699762167 Mon Sep 17 00:00:00 2001 From: Justin Malandruccolo Date: Tue, 16 Jul 2024 11:07:14 -0400 Subject: [PATCH] Add ad inspector to native template example (#1131) * Add ad inspector button * ioS 12 * formatted --------- Co-authored-by: Justin Malandruccolo --- .../ios/Flutter/AppFrameworkInfo.plist | 2 +- .../ios/Runner.xcodeproj/project.pbxproj | 3 + .../lib/app_bar_item.dart | 9 ++ .../native_template_example/lib/main.dart | 86 +++++++++++-------- .../native_template_example/pubspec.yaml | 2 +- 5 files changed, 62 insertions(+), 40 deletions(-) create mode 100644 samples/admob/native_template_example/lib/app_bar_item.dart diff --git a/samples/admob/native_template_example/ios/Flutter/AppFrameworkInfo.plist b/samples/admob/native_template_example/ios/Flutter/AppFrameworkInfo.plist index 9625e105d..7c5696400 100644 --- a/samples/admob/native_template_example/ios/Flutter/AppFrameworkInfo.plist +++ b/samples/admob/native_template_example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/samples/admob/native_template_example/ios/Runner.xcodeproj/project.pbxproj b/samples/admob/native_template_example/ios/Runner.xcodeproj/project.pbxproj index 59f394fe2..45c507223 100644 --- a/samples/admob/native_template_example/ios/Runner.xcodeproj/project.pbxproj +++ b/samples/admob/native_template_example/ios/Runner.xcodeproj/project.pbxproj @@ -378,6 +378,7 @@ DEVELOPMENT_TEAM = EQHXZ8M8AV; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -507,6 +508,7 @@ DEVELOPMENT_TEAM = EQHXZ8M8AV; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -530,6 +532,7 @@ DEVELOPMENT_TEAM = EQHXZ8M8AV; 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/native_template_example/lib/app_bar_item.dart b/samples/admob/native_template_example/lib/app_bar_item.dart new file mode 100644 index 000000000..e77175cee --- /dev/null +++ b/samples/admob/native_template_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/native_template_example/lib/main.dart b/samples/admob/native_template_example/lib/main.dart index 4fac7c35c..06764c077 100644 --- a/samples/admob/native_template_example/lib/main.dart +++ b/samples/admob/native_template_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 native ad. +/// An example app that loads a native ad. class NativeExample extends StatefulWidget { const NativeExample({super.key}); @@ -21,10 +22,9 @@ class NativeExample extends StatefulWidget { } class NativeExampleState extends State { - static const privacySettingsText = 'Privacy Settings'; - final _consentManager = ConsentManager(); var _isMobileAdsInitializeCalled = false; + var _isPrivacyOptionsRequired = false; NativeAd? _nativeAd; bool _nativeAdIsLoaded = false; @@ -46,6 +46,9 @@ class NativeExampleState extends State { "${consentGatheringError.errorCode}: ${consentGatheringError.message}"); } + // Check if a privacy options entry point is required. + _getIsPrivacyOptionsRequired(); + // Attempt to initialize the Mobile Ads SDK. _initializeMobileAdsSDK(); }); @@ -60,10 +63,7 @@ class NativeExampleState extends State { title: 'Native Example', home: Scaffold( appBar: AppBar( - title: const Text('Native Example'), - actions: _isMobileAdsInitializeCalled - ? _privacySettingsAppBarAction() - : null), + title: const Text('Native Example'), actions: _appBarActions()), body: SizedBox( height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, @@ -96,33 +96,36 @@ class NativeExampleState 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}"); + } + }); + } }) ]; } @@ -185,6 +188,15 @@ class NativeExampleState 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 { @@ -192,14 +204,12 @@ class NativeExampleState 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(); } diff --git a/samples/admob/native_template_example/pubspec.yaml b/samples/admob/native_template_example/pubspec.yaml index 107d45ac7..5c0ec8d84 100644 --- a/samples/admob/native_template_example/pubspec.yaml +++ b/samples/admob/native_template_example/pubspec.yaml @@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: '>=2.18.0 <3.0.0' + sdk: '>=3.2.0 <4.0.0' # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions