Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added UMP SDK integration to Interstitial sample #1065

Merged
merged 15 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions samples/admob/interstitial_example/lib/consent_manager.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
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 {
/// 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);
}
}
119 changes: 112 additions & 7 deletions samples/admob/interstitial_example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'consent_manager.dart';

void main() {
WidgetsFlutterBinding.ensureInitialized();
MobileAds.instance.initialize();
runApp(const MaterialApp(
home: InterstitialExample(),
));
Expand All @@ -21,9 +22,16 @@ class InterstitialExample extends StatefulWidget {
}

class InterstitialExampleState extends State<InterstitialExample> {
static const privacySettingsText = 'Privacy Settings';

InterstitialAd? _interstitialAd;
final _consentManager = ConsentManager();
final _gameLength = 5;
var _gamePaused = false;
var _gameOver = false;
var _isMobileAdsInitializeCalled = false;
late var _counter = _gameLength;
Timer? _timer;

final String _adUnitId = Platform.isAndroid
? 'ca-app-pub-3940256099942544/1033173712'
Expand All @@ -33,14 +41,46 @@ class InterstitialExampleState extends State<InterstitialExample> {
void initState() {
super.initState();

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

// Kick off the first play of the "game".
_startNewGame();

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

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

void _startNewGame() {
setState(() => _counter = _gameLength);

_loadAd();
_starTimer();
_startTimer();
_gameOver = false;
_gamePaused = false;
}

void _pauseGame() {
if (_gameOver || _gamePaused) {
return;
}
_timer?.cancel();
_gamePaused = true;
}

void _resumeGame() {
if (_gameOver || !_gamePaused) {
return;
}
_startTimer();
_gamePaused = false;
}

@override
Expand All @@ -50,6 +90,9 @@ class InterstitialExampleState extends State<InterstitialExample> {
home: Scaffold(
appBar: AppBar(
title: const Text('Interstitial Example'),
actions: _isMobileAdsInitializeCalled
? _privacySettingsAppBarAction()
: null,
),
body: Stack(
children: [
Expand All @@ -74,6 +117,7 @@ class InterstitialExampleState extends State<InterstitialExample> {
child: TextButton(
onPressed: () {
_startNewGame();
_loadAd();
},
child: const Text('Play Again'),
),
Expand All @@ -85,8 +129,48 @@ class InterstitialExampleState extends State<InterstitialExample> {
);
}

List<Widget> _privacySettingsAppBarAction() {
return <Widget>[
// 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<String>(
onSelected: (String result) {
if (result == privacySettingsText) {
_pauseGame();
_consentManager.showPrivacyOptionsForm((formError) {
if (formError != null) {
debugPrint(
"${formError.errorCode}: ${formError.message}");
}
_resumeGame();
});
}
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: privacySettingsText,
child: Text(privacySettingsText))
],
));
})
];
}

/// Loads an interstitial ad.
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.canRequestAds();
if (!canRequestAds) {
return;
}

InterstitialAd.load(
adUnitId: _adUnitId,
request: const AdRequest(),
Expand Down Expand Up @@ -138,17 +222,38 @@ class InterstitialExampleState extends State<InterstitialExample> {
));
}

void _starTimer() {
Timer.periodic(const Duration(seconds: 1), (timer) {
void _startTimer() {
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() => _counter--);

if (_counter == 0) {
_gameOver = true;
_showAlert(context);
timer.cancel();
}
});
}

/// 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.canRequestAds();
if (canRequestAds) {
setState(() {
_isMobileAdsInitializeCalled = true;
});

// Initialize the Mobile Ads SDK.
MobileAds.instance.initialize();
// Load an ad.
_loadAd();
}
}

@override
void dispose() {
_interstitialAd?.dispose();
Expand Down
2 changes: 1 addition & 1 deletion samples/admob/interstitial_example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ environment:
dependencies:
flutter:
sdk: flutter
google_mobile_ads: ^4.0.0
google_mobile_ads: ^5.1.0

dev_dependencies:
flutter_test:
Expand Down