Questa guida è rivolta ai publisher che integrano gli annunci apertura app utilizzando l'SDK Google Mobile Ads.
Gli annunci apertura app sono un formato speciale destinato ai publisher che vogliono monetizzare le schermate di caricamento delle app. Gli annunci apertura app possono essere chiusi in qualsiasi momento e sono progettati per essere mostrati quando gli utenti portano la tua app in primo piano.
Gli annunci apertura app mostrano automaticamente una piccola area di branding, in modo che gli utenti sappiano di essere all'interno della tua app. Ecco un esempio di annuncio apertura app:
Prerequisiti
- Completa la Guida introduttiva.
Esegui sempre test con annunci di prova
Quando crei e testi le tue app, assicurati di utilizzare annunci di prova anziché annunci pubblicati in produzione. In caso contrario, il tuo account potrebbe essere sospeso.
Il modo più semplice per caricare gli annunci di prova è utilizzare il nostro ID unità pubblicitaria di prova dedicato per gli annunci di apertura dell'app:
/21775744923/example/app-open
È stato configurato appositamente per restituire annunci di prova per ogni richiesta e puoi usarlo nelle tue app durante la programmazione, i test e il debug. Assicurati solo di sostituirlo con il tuo ID unità pubblicitaria prima di pubblicare l'app.
Per saperne di più sul funzionamento degli annunci di prova dell'SDK Google Mobile Ads, consulta Attivare gli annunci di prova.
Estendere la classe Application
Crea una nuova classe che estenda la classe Application
e aggiungi il seguente codice per inizializzare l'SDK Google Mobile Ads all'avvio dell'app.
Kotlin
/** Application class that initializes, loads and show ads when activities change states. */
class MyApplication : Application() {
override fun onCreate() {
super<Application>.onCreate()
CoroutineScope(Dispatchers.IO).launch {
// Initialize the Mobile Ads SDK synchronously on a background thread.
MobileAds.initialize(this@MyApplication, InitializationConfig.Builder(APP_ID).build()) {}
}
}
private companion object {
// Sample AdMob App ID.
const val APP_ID = "ca-app-pub-3940256099942544~3347511713"
}
}
Java
/** Application class that initializes, loads and show ads when activities change states. */
public class MyApplication extends Application {
// Sample AdMob App ID.
private static final String APP_ID = "ca-app-pub-3940256099942544~3347511713";
@Override
public void onCreate() {
super.onCreate();
new Thread(
() -> {
// Initialize the Google Mobile Ads SDK on a background thread.
MobileAds.initialize(
MyApplication.this,
new InitializationConfig.Builder(APP_ID).build(),
initializationStatus -> {});
})
.start();
}
}
In questo modo viene inizializzato l'SDK e viene fornito lo scheletro in cui registrerai in un secondo momento gli eventi di impostazione in primo piano dell'app.
Aggiungi il seguente codice a AndroidManifest.xml
:
<!-- TODO: Update to reference your actual package name. -->
<application
android:name="com.google.android.gms.example.appopendemo.MyApplication" ...>
...
</application>
Implementa il componente della società di servizi pubblici
L'annuncio deve essere visualizzato rapidamente, quindi è meglio caricarlo prima di doverlo mostrare. In questo modo, avrai un annuncio pronto non appena l'utente entrerà nella tua app.
Implementa un componente di utilità AppOpenAdManager
per effettuare richieste di annunci prima di quando devi mostrare l'annuncio.
Kotlin
/**
* Interface definition for a callback to be invoked when an app open ad is complete (i.e. dismissed
* or fails to show).
*/
fun interface OnShowAdCompleteListener {
fun onShowAdComplete()
}
/** Singleton object that loads and shows app open ads. */
object AppOpenAdManager {
private var appOpenAd: AppOpenAd? = null
private var isLoadingAd = false
var isShowingAd = false
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Showing the app open ad itself does not require a context.
*/
fun loadAd(context: Context) {
// We will implement this later.
}
/**
* Show the ad if one isn't already showing.
*
* @param activity the activity that shows the app open ad.
* @param onShowAdCompleteListener the listener to be notified when an app open ad is complete.
*/
fun showAdIfAvailable(activity: Activity, onShowAdCompleteListener: OnShowAdCompleteListener?) {
// We will implement this later.
}
/** Check if ad exists and can be shown. */
private fun isAdAvailable(): Boolean {
return appOpenAd != null
}
}
Java
/** Singleton object that loads and shows app open ads. */
public class AppOpenAdManager {
/**
* Interface definition for a callback to be invoked when an app open ad is complete (i.e.
* dismissed or fails to show).
*/
public interface OnShowAdCompleteListener {
void onShowAdComplete();
}
private static AppOpenAdManager instance;
private AppOpenAd appOpenAd;
private boolean isLoadingAd = false;
private boolean isShowingAd = false;
/** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
private long loadTime = 0;
public static synchronized AppOpenAdManager getInstance() {
if (instance == null) {
instance = new AppOpenAdManager();
}
return instance;
}
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
public void loadAd(@NonNull Context context) {
// We will implement this later.
}
/**
* Show the ad if one isn't already showing.
*
* @param activity the activity that shows the app open ad.
* @param onShowAdCompleteListener the listener to be notified when an app open ad is complete.
*/
public void showAdIfAvailable(
@NonNull Activity activity, @Nullable OnShowAdCompleteListener onShowAdCompleteListener) {
// We will implement this later.
}
/** Check if ad exists and can be shown. */
private boolean isAdAvailable() {
return appOpenAd != null
}
}
Carica un annuncio
Il passaggio successivo consiste nel compilare il metodo loadAd()
e gestire i callback relativi al caricamento degli annunci.
Kotlin
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
fun loadAd(context: Context) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAd || isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is either loading or has already loaded.")
return
}
isLoadingAd = true
AppOpenAd.load(
AdRequest.Builder(AppOpenFragment.AD_UNIT_ID).build(),
object : AdLoadCallback<AppOpenAd> {
/**
* Called when an app open ad has loaded.
*
* @param ad the loaded app open ad.
*/
override fun onAdLoaded(ad: AppOpenAd) {
// Called when an ad has loaded.
appOpenAd = ad
isLoadingAd = false
Log.d(Constant.TAG, "App open ad loaded.")
}
/**
* Called when an app open ad has failed to load.
*
* @param loadAdError the error.
*/
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
isLoadingAd = false
Log.w(Constant.TAG, "App open ad failed to load: $loadAdError")
}
},
)
}
Java
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
public void loadAd(@NonNull Context context) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAd || isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is either loading or has already loaded.");
return;
}
isLoadingAd = true;
AppOpenAd.load(
new AdRequest.Builder(AppOpenFragment.AD_UNIT_ID).build(),
new AdLoadCallback<AppOpenAd>() {
@Override
public void onAdLoaded(@NonNull AppOpenAd ad) {
appOpenAd = ad;
isLoadingAd = false;
Log.d(Constant.TAG, "App open ad loaded.");
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
isLoadingAd = false;
Log.w(Constant.TAG, "App open ad failed to load: " + loadAdError);
}
});
}
Mostrare l'annuncio e gestire gli eventi di callback a schermo intero
L'implementazione più comune dell'apertura dell'app consiste nel tentare di mostrare un annuncio apertura app nei pressi del lancio dell'app, avviare i contenuti dell'app se l'annuncio non è pronto e precaricare un altro annuncio per la prossima opportunità di apertura dell'app. Consulta Indicazioni per gli annunci apertura app per esempi di implementazione.
Il seguente codice mostra come mostrare e ricaricare successivamente un annuncio:
Kotlin
/**
* Show the ad if one isn't already showing.
*
* @param activity the activity that shows the app open ad.
* @param onShowAdCompleteListener the listener to be notified when an app open ad is complete.
*/
fun showAdIfAvailable(activity: Activity, onShowAdCompleteListener: OnShowAdCompleteListener?) {
// If the app open ad is already showing, do not show the ad again.
if (isShowingAd) {
Log.d(Constant.TAG, "App open ad is already showing.")
onShowAdCompleteListener?.onShowAdComplete()
return
}
// If the app open ad is not available yet, invoke the callback.
if (!isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is not ready yet.")
onShowAdCompleteListener?.onShowAdComplete()
return
}
appOpenAd?.adEventCallback =
object : AppOpenAdEventCallback {
override fun onAdShowedFullScreenContent() {
Log.d(Constant.TAG, "App open ad showed.")
}
override fun onAdDismissedFullScreenContent() {
Log.d(Constant.TAG, "App open ad dismissed.")
appOpenAd = null
isShowingAd = false
onShowAdCompleteListener?.onShowAdComplete()
loadAd(activity)
}
override fun onAdFailedToShowFullScreenContent(
fullScreenContentError: FullScreenContentError
) {
appOpenAd = null
isShowingAd = false
Log.w(Constant.TAG, "App open ad failed to show: $fullScreenContentError")
onShowAdCompleteListener?.onShowAdComplete()
loadAd(activity)
}
override fun onAdImpression() {
Log.d(Constant.TAG, "App open ad recorded an impression.")
}
override fun onAdClicked() {
Log.d(Constant.TAG, "App open ad recorded a click.")
}
}
isShowingAd = true
appOpenAd?.show(activity)
}
Java
/**
* Show the ad if one isn't already showing.
*
* @param activity the activity that shows the app open ad.
* @param onShowAdCompleteListener the listener to be notified when an app open ad is complete.
*/
public void showAdIfAvailable(
@NonNull Activity activity, @Nullable OnShowAdCompleteListener onShowAdCompleteListener) {
// If the app open ad is already showing, do not show the ad again.
if (isShowingAd) {
Log.d(Constant.TAG, "App open ad is already showing.");
if (onShowAdCompleteListener != null) {
onShowAdCompleteListener.onShowAdComplete();
}
return;
}
// If the app open ad is not available yet, invoke the callback.
if (!isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is not ready yet.");
if (onShowAdCompleteListener != null) {
onShowAdCompleteListener.onShowAdComplete();
}
return;
}
appOpenAd.setAdEventCallback(
new AppOpenAdEventCallback() {
@Override
public void onAdShowedFullScreenContent() {
Log.d(Constant.TAG, "App open ad shown.");
}
@Override
public void onAdDismissedFullScreenContent() {
Log.d(Constant.TAG, "App open ad dismissed.");
appOpenAd = null;
isShowingAd = false;
if (onShowAdCompleteListener != null) {
onShowAdCompleteListener.onShowAdComplete();
}
loadAd(activity);
}
@Override
public void onAdFailedToShowFullScreenContent(
@NonNull FullScreenContentError fullScreenContentError) {
appOpenAd = null;
isShowingAd = false;
Log.w(Constant.TAG, "App open ad failed to show: " + fullScreenContentError);
if (onShowAdCompleteListener != null) {
onShowAdCompleteListener.onShowAdComplete();
}
loadAd(activity);
}
@Override
public void onAdImpression() {
Log.d(Constant.TAG, "App open ad recorded an impression.");
}
@Override
public void onAdClicked() {
Log.d(Constant.TAG, "App open ad recorded a click.");
}
});
isShowingAd = true;
appOpenAd.show(activity);
}
AppOpenAdEventCallback
gestisce eventi come la visualizzazione dell'annuncio, la mancata visualizzazione o la chiusura dell'annuncio.
Valuta la scadenza degli annunci
Per assicurarti di non mostrare un annuncio scaduto, aggiungi un metodo al AppOpenAdManager
che controlla quanto tempo è trascorso dal caricamento del riferimento dell'annuncio. Quindi, utilizza questo metodo per verificare se l'annuncio è ancora valido.
Kotlin
object AppOpenAdManager {
// ...
/** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
private var loadTime: Long = 0;
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
fun loadAd(context: Context) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAd || isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is either loading or has already loaded.")
return
}
isLoadingAd = true
AppOpenAd.load(
AdRequest.Builder(AppOpenFragment.AD_UNIT_ID).build(),
object : AdLoadCallback<AppOpenAd> {
/**
* Called when an app open ad has loaded.
*
* @param ad the loaded app open ad.
*/
override fun onAdLoaded(ad: AppOpenAd) {
// Called when an ad has loaded.
appOpenAd = ad
isLoadingAd = false
loadTime = Date().time
Log.d(Constant.TAG, "App open ad loaded.")
}
/**
* Called when an app open ad has failed to load.
*
* @param loadAdError the error.
*/
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
isLoadingAd = false
Log.w(Constant.TAG, "App open ad failed to load: $loadAdError")
}
},
)
}
// ...
/** Check if ad was loaded more than n hours ago. */
private fun wasLoadTimeLessThanNHoursAgo(numHours: Long): Boolean {
val dateDifference: Long = Date().time - loadTime
val numMilliSecondsPerHour: Long = 3600000
return dateDifference < numMilliSecondsPerHour * numHours
}
/** Check if ad exists and can be shown. */
private fun isAdAvailable(): Boolean {
// App open ads expire after four hours. Ads rendered more than four hours after request time
// are no longer valid and may not earn revenue.
return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4)
}
}
Java
public class AppOpenAdManager {
// ...
/** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
private long loadTime = 0;
/**
* Load an ad.
*
* @param context a context used to perform UI-related operations (e.g. display Toast messages).
* Loading the app open ad itself does not require a context.
*/
public void loadAd(@NonNull Context context) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAd || isAdAvailable()) {
Log.d(Constant.TAG, "App open ad is either loading or has already loaded.");
return;
}
isLoadingAd = true;
AppOpenAd.load(
new AdRequest.Builder(AppOpenFragment.AD_UNIT_ID).build(),
new AdLoadCallback<AppOpenAd>() {
@Override
public void onAdLoaded(@NonNull AppOpenAd ad) {
appOpenAd = ad;
isLoadingAd = false;
loadTime = new Date().getTime();
Log.d(Constant.TAG, "App open ad loaded.");
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
isLoadingAd = false;
Log.w(Constant.TAG, "App open ad failed to load: " + loadAdError);
}
});
}
// ...
/** Check if ad was loaded more than n hours ago. */
private boolean wasLoadTimeLessThanNHoursAgo(long numHours) {
long dateDifference = new Date().getTime() - loadTime;
long numMilliSecondsPerHour = 3600000L;
return dateDifference < numMilliSecondsPerHour * numHours;
}
/** Check if ad exists and can be shown. */
private boolean isAdAvailable() {
// App open ads expire after four hours. Ads rendered more than four hours after request time
// are no longer valid and may not earn revenue.
return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4);
}
}
Monitorare l'attività corrente
Per pubblicare l'annuncio, devi avere un contesto Activity
. Per tenere traccia dell'attività più aggiornata in uso, registrati e implementa Application.ActivityLifecycleCallbacks
.
Kotlin
class MyApplication : Application(), Application.ActivityLifecycleCallbacks {
private var currentActivity: Activity? = null
override fun onCreate() {
super<Application>.onCreate()
registerActivityLifecycleCallbacks(this)
}
/** ActivityLifecycleCallback methods. */
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {
currentActivity = activity
}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
// ...
}
Java
public class MyApplication extends Application
implements Application.ActivityLifecycleCallbacks {
private Activity currentActivity;
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
/** ActivityLifecycleCallback methods. */
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {}
@Override
public void onActivityStarted(@NonNull Activity activity) {
currentActivity = activity;
}
@Override
public void onActivityResumed(@NonNull Activity activity) {}
@Override
public void onActivityPaused(@NonNull Activity activity) {}
@Override
public void onActivityStopped(@NonNull Activity activity) {}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {}
// ...
}
registerActivityLifecycleCallbacks
ti consente di ascoltare tutti gli eventi Activity
. Monitorando l'avvio e l'interruzione delle attività, puoi tenere traccia di un riferimento all'Activity
corrente, che poi utilizzerai per presentare l'annuncio di apertura dell'app.
Ascolta gli eventi di impostazione in primo piano dell'app
Aggiungi le librerie al file gradle
Per ricevere una notifica sugli eventi di impostazione in primo piano dell'app, devi registrare un
DefaultLifecycleObserver
. Aggiungi la dipendenza al file di build a livello di app:
Kotlin
dependencies { implementation("com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:0.17.0-alpha02") implementation("androidx.lifecycle:lifecycle-process:2.8.3") }
Trendy
dependencies { implementation 'com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:0.17.0-alpha02' implementation 'androidx.lifecycle:lifecycle-process:2.8.3' }
Implementa l'interfaccia dell'osservatore del ciclo di vita
Puoi rilevare gli eventi in primo piano implementando l'interfaccia DefaultLifecycleObserver
.
Implementa l'evento onStart
per mostrare l'annuncio di apertura dell'app.
Kotlin
class MyApplication :
Application(), Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {
private var currentActivity: Activity? = null
override fun onCreate() {
super<Application>.onCreate()
registerActivityLifecycleCallbacks(this)
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
/**
* DefaultLifecycleObserver method that shows the app open ad when the app moves to foreground.
*/
override fun onStart(owner: LifecycleOwner) {
currentActivity?.let { activity ->
AppOpenAdManager.showAdIfAvailable(activity, null)
}
}
// ...
}
Java
public class MyApplication extends Application
implements Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {
private Activity currentActivity;
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
/**
* DefaultLifecycleObserver method that shows the app open ad when the app moves to foreground.
*/
@Override
public void onStart(@NonNull LifecycleOwner owner) {
if (currentActivity == null) {
return;
}
AppOpenAdManager.getInstance().showAdIfAvailable(currentActivity, null);
}
// ...
}
Avviamenti a freddo e schermate di caricamento
Finora la documentazione presupponeva che tu mostri gli annunci apertura app solo quando gli utenti attivano l'app in primo piano quando è sospesa in memoria. Gli "avvii a freddo" si verificano quando la tua app viene avviata, ma non era stata precedentemente sospesa in memoria.
Un esempio di avvio a freddo è quando un utente apre l'app per la prima volta. Con gli avvii a freddo, non avrai un annuncio di apertura app caricato in precedenza e pronto per essere mostrato subito. Il ritardo tra la richiesta di un annuncio e la ricezione di un annuncio di risposta può creare una situazione in cui gli utenti sono in grado di utilizzare brevemente la tua app prima di essere sorpresi da un annuncio fuori contesto. Questo approccio deve essere evitato perché rappresenta un'esperienza utente negativa.
Il modo migliore per utilizzare gli annunci apertura app all'avvio a freddo è utilizzare una schermata di caricamento per caricare gli asset del gioco o dell'app e mostrare l'annuncio solo dalla schermata di caricamento. Se il caricamento dell'app è stato completato e l'utente è stato indirizzato ai contenuti principali dell'app, non mostrare l'annuncio.
Best practice
Gli annunci apertura app ti consentono di monetizzare la schermata di caricamento della tua app, quando viene avviata per la prima volta e durante i passaggi da un'app all'altra, ma è importante tenere presente le best practice per consentire agli utenti di utilizzare la tua app con piacere. Ti consigliamo di:
- Mostra il primo annuncio di apertura dell'app dopo che gli utenti l'hanno utilizzata alcune volte.
- Mostra gli annunci apertura app nei momenti in cui gli utenti altrimenti dovrebbero attendere per il caricamento dell'app.
- Se sotto l'annuncio di apertura dell'app è presente una schermata di caricamento che completa il caricamento prima che l'annuncio venga chiuso, ti consigliamo di chiuderla nel metodo
onAdDismissedFullScreenContent()
.
Esempio
Scarica ed esegui la app di esempio che mostra l'utilizzo dell'SDK Google Mobile Ads di nuova generazione.