Os anúncios de abertura do app são um formato especial destinado a publishers que querem gerar receita com as telas de carregamento do app. Eles podem ser fechados a qualquer momento e são projetados para aparecer quando os usuários colocam seu app em primeiro plano.
Esses anúncios mostram automaticamente uma pequena área de branding para que as pessoas saibam que estão no seu app. Esta é a aparência de um anúncio de abertura do app:
Pré-requisitos
- Plug-in do Flutter 0.13.6 ou versão mais recente.
- Leia o guia para iniciantes. O plug-in de anúncios para dispositivos móveis do Google para Flutter já precisa ter sido importado para o app.
Sempre usar anúncios de teste
Ao criar e testar seus apps, use anúncios de teste em vez de anúncios de produção ativos. Caso contrário, sua conta poderá ser suspensa.
A maneira mais fácil de carregar anúncios de teste é usar nossos IDs de bloco de anúncios de teste dedicados para anúncios premiados do Android e iOS:
Android
ca-app-pub-3940256099942544/9257395921
iOS
ca-app-pub-3940256099942544/5575463023
Eles foram configurados especialmente para retornar anúncios de teste em todas as solicitações, e você pode usá-los nos seus próprios apps durante a programação, os testes e a depuração. Não se esqueça de substituí-los pelo seu ID do bloco de anúncios antes de publicar o app.
Implementação
Principais etapas para integrar anúncios de abertura do app:
- Crie uma classe de utilitários que carregue um anúncio antes de você precisar mostrá-lo.
- Carregue um anúncio.
- Registre-se para callbacks e mostre o anúncio.
- Inscreva-se em
AppStateEventNotifier.appStateStream
para veicular o anúncio em eventos de primeiro plano.
Criar uma classe de utilitários
Crie uma classe chamada AppOpenAdManager
para carregar o anúncio. Essa classe gerencia uma variável de instância para acompanhar um anúncio carregado e o ID do bloco de anúncios de cada plataforma.
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'dart:io' show Platform;
class AppOpenAdManager {
String adUnitId = Platform.isAndroid
? 'ca-app-pub-3940256099942544/9257395921'
: 'ca-app-pub-3940256099942544/5575463023';
AppOpenAd? _appOpenAd;
bool _isShowingAd = false;
/// Load an AppOpenAd.
void loadAd() {
// We will implement this below.
}
/// Whether an ad is available to be shown.
bool get isAdAvailable {
return _appOpenAd != null;
}
}
Carregar um anúncio
O anúncio de abertura do app precisa já estar pronto quando os usuários entram no app. Implemente uma classe de utilitários para fazer solicitações de anúncios antes de precisar mostrar o anúncio.
É possível carregar um anúncio usando o método load
na classe AppOpenAd
. O método de carregamento requer um ID do bloco de anúncios, um modo de orientação, um objeto AdRequest
e um gerenciador de conclusão que é ativado quando o carregamento do anúncio é concluído ou apresenta falha. O objeto AppOpenAd
carregado é fornecido como um parâmetro no gerenciador de conclusão. O exemplo abaixo mostra como carregar um AppOpenAd
.
public class AppOpenAdManager {
...
/// Load an AppOpenAd.
void loadAd() {
AppOpenAd.load(
adUnitId: adUnitId,
adRequest: AdRequest(),
adLoadCallback: AppOpenAdLoadCallback(
onAdLoaded: (ad) {
_appOpenAd = ad;
},
onAdFailedToLoad: (error) {
print('AppOpenAd failed to load: $error');
// Handle the error.
},
),
);
}
}
Mostrar o anúncio e processar callbacks de tela cheia
Antes de veicular o anúncio, registre um FullScreenContentCallback
para cada evento de anúncio que você quer acompanhar.
public class AppOpenAdManager {
...
public void showAdIfAvailable() {
if (!isAdAvailable) {
print('Tried to show ad before available.');
loadAd();
return;
}
if (_isShowingAd) {
print('Tried to show ad while already showing an ad.');
return;
}
// Set the fullScreenContentCallback and show the ad.
_appOpenAd!.fullScreenContentCallback = FullScreenContentCallback(
onAdShowedFullScreenContent: (ad) {
_isShowingAd = true;
print('$ad onAdShowedFullScreenContent');
},
onAdFailedToShowFullScreenContent: (ad, error) {
print('$ad onAdFailedToShowFullScreenContent: $error');
_isShowingAd = false;
ad.dispose();
_appOpenAd = null;
},
onAdDismissedFullScreenContent: (ad) {
print('$ad onAdDismissedFullScreenContent');
_isShowingAd = false;
ad.dispose();
_appOpenAd = null;
loadAd();
},
);
}
}
Se um usuário sair do seu app clicando em um anúncio de abertura de app e depois voltar, não mostre outro anúncio do mesmo tipo.
Detectar eventos do app em primeiro plano
Para receber notificações sobre eventos do app em primeiro plano, inscreva-se em AppStateEventNotifier.appStateStream
e detecte eventos foreground
.
import 'package:app_open_example/app_open_ad_manager.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
/// Listens for app foreground events and shows app open ads.
class AppLifecycleReactor {
final AppOpenAdManager appOpenAdManager;
AppLifecycleReactor({required this.appOpenAdManager});
void listenToAppStateChanges() {
AppStateEventNotifier.startListening();
AppStateEventNotifier.appStateStream
.forEach((state) => _onAppStateChanged(state));
}
void _onAppStateChanged(AppState appState) {
// Try to show an app open ad if the app is being resumed and
// we're not already showing an app open ad.
if (appState == AppState.foreground) {
appOpenAdManager.showAdIfAvailable();
}
}
}
Agora você pode inicializar o AppLifecycleReactor
e começar a detectar mudanças no ciclo de vida do app. Por exemplo, na página inicial:
import 'package:app_open_example/app_open_ad_manager.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'app_lifecycle_reactor.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
MobileAds.instance.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App Open Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'App Open Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
/// Example home page for an app open ad.
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
late AppLifecycleReactor _appLifecycleReactor;
@override
void initState() {
super.initState();
AppOpenAdManager appOpenAdManager = AppOpenAdManager()..loadAd();
_appLifecycleReactor = AppLifecycleReactor(
appOpenAdManager: appOpenAdManager);
}
Considerar a validade dos anúncios
Para não veicular um anúncio expirado, adicione um carimbo de data/hora ao AppOpenAdManager
para saber há quanto tempo o anúncio foi carregado.
Depois, use essa marcação para verificar se o anúncio continua válido.
/// Utility class that manages loading and showing app open ads.
class AppOpenAdManager {
...
/// Maximum duration allowed between loading and showing the ad.
final Duration maxCacheDuration = Duration(hours: 4);
/// Keep track of load time so we don't show an expired ad.
DateTime? _appOpenLoadTime;
...
/// Load an AppOpenAd.
void loadAd() {
AppOpenAd.load(
adUnitId: adUnitId,
orientation: AppOpenAd.orientationPortrait,
adRequest: AdRequest(),
adLoadCallback: AppOpenAdLoadCallback(
onAdLoaded: (ad) {
print('$ad loaded');
_appOpenLoadTime = DateTime.now();
_appOpenAd = ad;
},
onAdFailedToLoad: (error) {
print('AppOpenAd failed to load: $error');
},
),
);
}
/// Shows the ad, if one exists and is not already being shown.
///
/// If the previously cached ad has expired, this just loads and caches a
/// new ad.
void showAdIfAvailable() {
if (!isAdAvailable) {
print('Tried to show ad before available.');
loadAd();
return;
}
if (_isShowingAd) {
print('Tried to show ad while already showing an ad.');
return;
}
if (DateTime.now().subtract(maxCacheDuration).isAfter(_appOpenLoadTime!)) {
print('Maximum cache duration exceeded. Loading another ad.');
_appOpenAd!.dispose();
_appOpenAd = null;
loadAd();
return;
}
// Set the fullScreenContentCallback and show the ad.
_appOpenAd!.fullScreenContentCallback = FullScreenContentCallback(...);
_appOpenAd!.show();
}
}
Inicializações a frio e telas de carregamento
Até agora, a documentação pressupõe que você só mostra anúncios de abertura do app no momento em que os usuários colocam o app em primeiro plano enquanto ele está suspenso na memória. As inicializações a frio ocorrem quando o app é iniciado, mas não estava suspenso na memória.
Um exemplo disso é quando um usuário abre seu app pela primeira vez. Com esse tipo de inicialização, não existe um anúncio de abertura do app carregado pronto para ser mostrado imediatamente. A demora entre a solicitação de um anúncio e o recebimento dele poderá criar uma situação em que os usuários conseguem usar seu app brevemente antes de serem surpreendidos por um anúncio fora de contexto. Evite essa experiência ruim do usuário.
A melhor maneira de usar anúncios de abertura do app em inicializações a frio é ter uma tela de carregamento para abrir os recursos do jogo ou app e mostrar o anúncio apenas nessa tela. Se o app tiver terminado de carregar e direcionado o usuário para o conteúdo principal, não mostre o anúncio.
Práticas recomendadas
Os anúncios de abertura do app ajudam a gerar receita com a tela de carregamento quando o app é aberto pela primeira vez e durante a troca de apps. Mas é importante seguir as práticas recomendadas abaixo para que as pessoas gostem de usar seu app.
- Mostre o primeiro anúncio de abertura do app depois que o usuário acessar o aplicativo algumas vezes.
- Mostre esses anúncios quando os usuários estão esperando o carregamento do app.
- Se o carregamento da tela abaixo do anúncio de abertura do app terminar antes que o anúncio seja dispensado, feche essa tela no manipulador de eventos
onAdDismissedFullScreenContent
.