Skip to content

Commit

Permalink
Added UMP SDK integration to App Open example
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Malandruccolo committed May 6, 2024
1 parent d4071e1 commit 8d9a3d9
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 5 deletions.
10 changes: 9 additions & 1 deletion samples/admob/app_open_example/lib/app_open_ad_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

// ignore_for_file: public_member_api_docs
import 'package:app_open_example/consent_manager.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'dart:io' show Platform;
Expand All @@ -33,7 +34,14 @@ class AppOpenAdManager {
: 'ca-app-pub-3940256099942544/5575463023';

/// Load an [AppOpenAd].
void loadAd() {
void loadAd() async {
// Only load an ad if the Mobile Ads SDK has gathered consent aligned with
// the app's configured messages.
var canRequestAds = await ConsentManager.instance.canRequestAds();
if (!canRequestAds) {
return;
}

AppOpenAd.load(
adUnitId: adUnitId,
request: const AdRequest(),
Expand Down
54 changes: 54 additions & 0 deletions samples/admob/app_open_example/lib/consent_manager.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'dart:async';

import 'package:google_mobile_ads/google_mobile_ads.dart';

typedef OnConsentGatheringCompleteListener = void Function(FormError? error);

/// The Google Mobile Ads SDK provides the User Messaging Platform (Google's IAB
/// Certified consent management platform) as one solution to capture consent for
/// users in GDPR impacted countries. This is an example and you can choose
/// another consent management platform to capture consent.
class ConsentManager {
ConsentManager._();
static final ConsentManager instance = ConsentManager._();

/// Helper variable to determine if the app can request ads.
Future<bool> canRequestAds() async {
return await ConsentInformation.instance.canRequestAds();
}

/// Helper variable to determine if the privacy options form is required.
Future<bool> isPrivacyOptionsRequired() async {
return await ConsentInformation.instance
.getPrivacyOptionsRequirementStatus() ==
PrivacyOptionsRequirementStatus.required;
}

/// Helper method to call the Mobile Ads SDK to request consent information
/// and load/show a consent form if necessary.
void gatherConsent(
OnConsentGatheringCompleteListener onConsentGatheringCompleteListener) {
// For testing purposes, you can force a DebugGeography of Eea or NotEea.
ConsentDebugSettings debugSettings = ConsentDebugSettings(
// debugGeography: DebugGeography.debugGeographyEea,
);
ConsentRequestParameters params =
ConsentRequestParameters(consentDebugSettings: debugSettings);

// Requesting an update to consent information should be called on every app launch.
ConsentInformation.instance.requestConsentInfoUpdate(params, () async {
ConsentForm.loadAndShowConsentFormIfRequired((loadAndShowError) {
// Consent has been gathered.
onConsentGatheringCompleteListener(loadAndShowError);
});
}, (FormError formError) {
onConsentGatheringCompleteListener(formError);
});
}

/// Helper method to call the Mobile Ads SDK method to show the privacy options form.
void showPrivacyOptionsForm(
OnConsentFormDismissedListener onConsentFormDismissedListener) {
ConsentForm.showPrivacyOptionsForm(onConsentFormDismissedListener);
}
}
79 changes: 76 additions & 3 deletions samples/admob/app_open_example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'app_lifecycle_reactor.dart';
import 'app_open_ad_manager.dart';

import 'consent_manager.dart';

void main() {
WidgetsFlutterBinding.ensureInitialized();
MobileAds.instance.initialize();
runApp(const MainApp());
}

Expand All @@ -48,16 +49,34 @@ class HomePage extends StatefulWidget {

/// Example home page for an app open ad.
class _HomePageState extends State<HomePage> {
static const privacySettingsText = 'Privacy Settings';

final _appOpenAdManager = AppOpenAdManager();
var _isMobileAdsInitializeCalled = false;
int _counter = 0;
late AppLifecycleReactor _appLifecycleReactor;

@override
void initState() {
super.initState();
AppOpenAdManager appOpenAdManager = AppOpenAdManager()..loadAd();

_appLifecycleReactor =
AppLifecycleReactor(appOpenAdManager: appOpenAdManager);
AppLifecycleReactor(appOpenAdManager: _appOpenAdManager);
_appLifecycleReactor.listenToAppStateChanges();

ConsentManager.instance.gatherConsent((consentGatheringError) {
if (consentGatheringError != null) {
// Consent not obtained in current session.
debugPrint(
"${consentGatheringError.errorCode}: ${consentGatheringError.message}");
}

// Attempt to initialize the Mobile Ads SDK.
_initializeMobileAdsSDK();
});

// This sample attempts to load ads using consent obtained in the previous session.
_initializeMobileAdsSDK();
}

void _incrementCounter() {
Expand All @@ -71,6 +90,8 @@ class _HomePageState extends State<HomePage> {
return Scaffold(
appBar: AppBar(
title: const Text('App Open Demo Home Page'),
actions:
_isMobileAdsInitializeCalled ? _privacySettingsAppBarAction() : [],
),
body: Center(
child: Column(
Expand All @@ -93,4 +114,56 @@ class _HomePageState extends State<HomePage> {
), // This trailing comma makes auto-formatting nicer for build methods.
);
}

List<Widget> _privacySettingsAppBarAction() {
return <Widget>[
// Regenerate the options menu to include a privacy setting.
FutureBuilder(
future: ConsentManager.instance.isPrivacyOptionsRequired(),
builder: (context, snapshot) {
final bool visibility = snapshot.data ?? false;
return Visibility(
visible: visibility,
child: PopupMenuButton<String>(
onSelected: (String result) {
if (result == privacySettingsText) {
ConsentManager.instance
.showPrivacyOptionsForm((formError) {
if (formError != null) {
debugPrint(
"${formError.errorCode}: ${formError.message}");
}
});
}
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: privacySettingsText,
child: Text(privacySettingsText))
],
));
})
];
}

/// Initialize the Mobile Ads SDK if the SDK has gathered consent aligned with
/// the app's configured messages.
void _initializeMobileAdsSDK() async {
if (_isMobileAdsInitializeCalled) {
return;
}

var canRequestAds = await ConsentManager.instance.canRequestAds();
if (canRequestAds) {
setState(() {
_isMobileAdsInitializeCalled = true;
});

// Initialize the Mobile Ads SDK.
MobileAds.instance.initialize();
// Load an ad.
_appOpenAdManager.loadAd();
}
}
}
6 changes: 5 additions & 1 deletion samples/admob/app_open_example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ environment:
sdk: '>=3.2.0 <4.0.0'

dependencies:
google_mobile_ads:
git:
url: https://github.com/googleads/googleads-mobile-flutter/
path: ./packages/google_mobile_ads

flutter:
sdk: flutter
google_mobile_ads: ^5.0.0

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 8d9a3d9

Please sign in to comment.