Quảng cáo khi mở ứng dụng

Tài liệu hướng dẫn này dành cho các nhà xuất bản tích hợp quảng cáo khi mở ứng dụng bằng cách sử dụng SDK Android quảng cáo trên thiết bị di động của Google.

Quảng cáo khi mở ứng dụng là một định dạng quảng cáo đặc biệt dành cho những nhà xuất bản muốn kiếm tiền từ màn hình tải ứng dụng của họ. Quảng cáo khi mở ứng dụng được thiết kế để xuất hiện khi người dùng chạy ứng dụng của bạn trên nền trước và họ có thể đóng quảng cáo này bất cứ lúc nào.

Quảng cáo khi mở ứng dụng tự động hiển thị một vùng nhỏ chứa thông tin thương hiệu để người dùng biết họ đang mở ứng dụng của bạn. Dưới đây là một ví dụ về cách hiển thị của quảng cáo khi mở ứng dụng:

Nhìn chung, bạn cần thực hiện các bước quan trọng sau đây:

  1. Mở rộng lớp Application để khởi chạy SDK GMA.
  2. Tạo một lớp tiện ích sẽ tải quảng cáo trước khi bạn cần hiển thị quảng cáo đó.
  3. Tải một quảng cáo.
  4. Theo dõi ActivityLifecycleCallbacks.
  5. Hiển thị quảng cáo và xử lý các lệnh gọi lại.
  6. Triển khai và đăng ký giao diện LifecycleObserver để hiển thị quảng cáo trong các sự kiện đưa lên nền trước.

Điều kiện tiên quyết

  • SDK quảng cáo trên thiết bị di động của Google phiên bản 19.4.0 trở lên.
  • Làm theo các hướng dẫn thiết lập trong Hướng dẫn bắt đầu.

Luôn kiểm tra bằng quảng cáo thử nghiệm

Khi tạo và thử nghiệm ứng dụng, hãy đảm bảo rằng bạn sử dụng quảng cáo thử nghiệm thay vì quảng cáo đang chạy thực tế. Chúng tôi sẽ tạm ngưng tài khoản của bạn nếu bạn không tuân thủ yêu cầu này.

Cách dễ nhất để tải quảng cáo thử nghiệm là dùng mã đơn vị quảng cáo thử nghiệm chúng tôi dành riêng cho quảng cáo khi mở ứng dụng:

ca-app-pub-3940256099942544/3419835294

Mã này được định cấu hình đặc biệt để trả về quảng cáo thử nghiệm cho mọi yêu cầu và bạn có thể dùng mã này trong khi viết mã, thử nghiệm và gỡ lỗi cho ứng dụng của mình. Bạn chỉ cần nhớ thay thế mã này bằng mã đơn vị quảng cáo của mình trước khi xuất bản ứng dụng.

Để biết thêm thông tin về cách hoạt động của quảng cáo thử nghiệm của SDK quảng cáo trên thiết bị di động, hãy xem bài viết về Quảng cáo thử nghiệm.

Mở rộng lớp Ứng dụng

Tạo một lớp mới tên là MyApplication và thêm mã sau:

package com.google.android.gms.example.appopendemo;

import android.app.Application;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;

/** The Application class that manages AppOpenManager. */
public class MyApplication extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    MobileAds.initialize(
        this,
        new OnInitializationCompleteListener() {
          @Override
          public void onInitializationComplete(InitializationStatus initializationStatus) {}
        });
  }
}

Thao tác này sẽ khởi tạo SDK và cung cấp bộ khung mà sau này bạn sẽ dùng để đăng ký các sự kiện đưa ứng dụng lên nền trước.

Tiếp theo, hãy thêm mã sau vào AndroidManifest.xml của bạn:

<application
    android:name="com.google.android.gms.example.appopendemo.MyApplication" ...>
...
</application>

Bạn nhớ tham chiếu tên thực tế của gói.

Triển khai lớp tiện ích

Quảng cáo của bạn cần phải nhanh chóng hiển thị. Do đó, tốt nhất là bạn nên tải quảng cáo trước khi cần hiển thị quảng cáo. Khi bạn làm như vậy, quảng cáo sẽ sẵn sàng hoạt động ngay khi người dùng truy cập vào ứng dụng của bạn. Hãy triển khai một lớp tiện ích để thực hiện các yêu cầu quảng cáo trước khi bạn cần hiển thị quảng cáo.

Tạo một lớp mới tên là AppOpenManager và nhập nội dung sau đây vào lớp đó:

import static androidx.lifecycle.Lifecycle.Event.ON_START;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.lifecycle.ProcessLifecycleOwner;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.appopen.AppOpenAd;
import java.util.Date;

/** Prefetches App Open Ads. */
public class AppOpenManager {
  private static final String LOG_TAG = "AppOpenManager";
  private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/3419835294";
  private AppOpenAd appOpenAd = null;

  private AppOpenAd.AppOpenAdLoadCallback loadCallback;

  private final MyApplication myApplication;

  /** Constructor */
  public AppOpenManager(MyApplication myApplication) {
    this.myApplication = myApplication;
  }

  /** Request an ad */
  public void fetchAd() {
    // We will implement this below.
  }

  /** Creates and returns ad request. */
  private AdRequest getAdRequest() {
    return new AdRequest.Builder().build();
  }

  /** Utility method that checks if ad exists and can be shown. */
  public boolean isAdAvailable() {
    return appOpenAd != null;
  }
}

Giao diện của lớp này sẽ quản lý một biến thực thể để theo dõi một quảng cáo đã tải, mã đơn vị quảng cáo và AppOpenAdLoadCallback.

Bây giờ, khi đã có lớp tiện ích, bạn có thể tạo bản sao lớp này trong lớp MyApplication của mình:

/** The Application class that manages AppOpenManager. */
public class MyApplication extends Application {

  private static AppOpenManager appOpenManager;

  @Override
  public void onCreate() {
    super.onCreate();
    MobileAds.initialize(
        this,
        new OnInitializationCompleteListener() {
          @Override
          public void onInitializationComplete(InitializationStatus initializationStatus) {}
        });

    appOpenManager = new AppOpenManager(this);

  }
}

Tải quảng cáo

Bước tiếp theo là điền vào phương thức fetchAd(). Hãy thêm nội dung dưới đây vào lớp AppOpenManager của bạn:

/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager {
  ...
  /** Request an ad */
  public void fetchAd() {
    // Have unused ad, no need to fetch another.
    if (isAdAvailable()) {
      return;
    }

    loadCallback =
        new AppOpenAd.AppOpenAdLoadCallback() {
          /**
           * Called when an app open ad has loaded.
           *
           * @param ad the loaded app open ad.
           */
          @Override
          public void onAdLoaded(AppOpenAd ad) {
            AppOpenManager.this.appOpenAd = ad;
          }

          /**
           * Called when an app open ad has failed to load.
           *
           * @param loadAdError the error.
           */
          @Override
          public void onAdFailedToLoad(LoadAdError loadAdError) {
            // Handle the error.
          }

        };
    AdRequest request = getAdRequest();
    AppOpenAd.load(
        myApplication, AD_UNIT_ID, request,
        AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, loadCallback);
  }
  ...
}

AppOpenAdLoadCallback có các phương thức được gọi khi AppOpenAd tải xong.

Theo dõi hoạt động hiện tại

Để hiển thị quảng cáo, bạn sẽ cần một ngữ cảnh Activity. Để theo dõi Hoạt động mới nhất mà người dùng của bạn đang sử dụng, hãy để lớp AppOpenManager triển khai giao diện Application.ActivityLifecycleCallbacks:

...
/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager implements Application.ActivityLifecycleCallbacks {

  private Activity currentActivity;

  ...

  /** ActivityLifecycleCallback methods */
  @Override
  public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}

  @Override
  public void onActivityStarted(Activity activity) {
    currentActivity = activity;
  }

  @Override
  public void onActivityResumed(Activity activity) {
    currentActivity = activity;
  }

  @Override
  public void onActivityStopped(Activity activity) {}

  @Override
  public void onActivityPaused(Activity activity) {}

  @Override
  public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {}

  @Override
  public void onActivityDestroyed(Activity activity) {
    currentActivity = null;
  }
}

Bằng cách theo dõi hoạt động hiện tại, bạn sẽ có ngữ cảnh dùng để hiển thị quảng cáo. Bây giờ, bạn cần đăng ký giao diện này bằng phương thức registerActivityLifecycleCallbacks Application trong hàm dựng AppOpenManager.

/** Constructor */
public AppOpenManager(MyApplication myApplication) {
  this.myApplication = myApplication;
  this.myApplication.registerActivityLifecycleCallbacks(this);
}

registerActivityLifecycleCallbacks cho phép bạn theo dõi tất cả sự kiện Activity. Bằng cách theo dõi thời điểm bắt đầu và hủy bỏ các hoạt động, bạn có thể theo dõi tệp tham chiếu đến Activity hiện tại mà sau đó, bạn sẽ dùng để hiển thị quảng cáo khi mở ứng dụng.

Hiển thị quảng cáo và xử lý các sự kiện gọi lại trên toàn màn hình

Thêm phương thức sau vào lớp AppOpenManager của bạn:

/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager implements Application.ActivityLifecycleCallbacks {
  ...
  private static boolean isShowingAd = false;

  /** Shows the ad if one isn't already showing. */
  public void showAdIfAvailable() {
    // Only show ad if there is not already an app open ad currently showing
    // and an ad is available.
    if (!isShowingAd && isAdAvailable()) {
      Log.d(LOG_TAG, "Will show ad.");

      FullScreenContentCallback fullScreenContentCallback =
          new FullScreenContentCallback() {
            @Override
            public void onAdDismissedFullScreenContent() {
              // Set the reference to null so isAdAvailable() returns false.
              AppOpenManager.this.appOpenAd = null;
              isShowingAd = false;
              fetchAd();
            }

            @Override
            public void onAdFailedToShowFullScreenContent(AdError adError) {}

            @Override
            public void onAdShowedFullScreenContent() {
              isShowingAd = true;
            }
          };

      appOpenAd.setFullScreenContentCallback(fullScreenContentCallback);
      appOpenAd.show(currentActivity);

    } else {
      Log.d(LOG_TAG, "Can not show ad.");
      fetchAd();
    }
  }
  ...
}

Phương thức này hiển thị quảng cáo, đặt lệnh trống trong lớp FullScreenContentCallback ẩn danh để xử lý các sự kiện như khi quảng cáo hiển thị, không hiển thị hoặc khi bị loại bỏ. Nếu người dùng quay lại ứng dụng của bạn sau khi rời khỏi ứng dụng bằng cách nhấp vào quảng cáo khi mở ứng dụng, thì phương thức này đảm bảo rằng ứng dụng sẽ không hiển thị một quảng cáo khi mở ứng dụng khác cho người dùng.

Theo dõi các sự kiện đưa ứng dụng lên nền trước

Thêm thư viện vào tệp gradle của bạn

Để được thông báo về các sự kiện đưa ứng dụng lên nền trước, bạn cần đăng ký một LifecycleObserver. Trước tiên, hãy chỉnh sửa tệp build.gradle cấp ứng dụng của bạn để bao gồm các thư viện LifecycleObserver:

apply plugin: 'com.android.application'

android {
   compileSdkVersion 28
   buildToolsVersion "29.0.0"
   defaultConfig {
       applicationId "com.google.android.gms.example.appopendemo"
       minSdkVersion 18
       targetSdkVersion 28
       versionCode 1
       versionName "1.0"
       testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
   }
   buildTypes {
       release {
           minifyEnabled false
           proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
       }
   }
}

dependencies {
   implementation 'androidx.appcompat:appcompat:1.0.2'
   implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

   implementation 'com.google.android.gms:play-services-ads:19.4.0'

   def lifecycle_version = "2.0.0"
   implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
   implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
   annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
}

Triển khai giao diện LifecycleObserver

Bạn có thể theo dõi các sự kiện đưa lên nền trước trong lớp AppOpenManager bằng cách triển khai giao diện LifecycleObserver. Hãy chỉnh sửa lớp của bạn bằng cách thêm nội dung sau:

package com.google.android.gms.example.appopendemo;

import static androidx.lifecycle.Lifecycle.Event.ON_START;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.lifecycle.ProcessLifecycleOwner;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.appopen.AppOpenAd;
import java.util.Date;

/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager implements LifecycleObserver, Application.ActivityLifecycleCallbacks {
  ...
  /** Constructor */
  public AppOpenManager(MyApplication myApplication) {
    this.myApplication = myApplication;
    this.myApplication.registerActivityLifecycleCallbacks(this);
    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
  }

  /** LifecycleObserver methods */
  @OnLifecycleEvent(ON_START)
  public void onStart() {
    showAdIfAvailable();
    Log.d(LOG_TAG, "onStart");
  }
  ...
}

Bằng cách đăng ký LifecycleObserver, ứng dụng của bạn sẽ được thông báo về các sự kiện chạy ứng dụng và đưa ứng dụng lên nền trước, đồng thời có thể hiển thị quảng cáo vào những thời điểm thích hợp.

Xem xét thời hạn quảng cáo

Để đảm bảo bạn không hiển thị quảng cáo đã hết hạn, hãy thêm một phương thức vào AppOpenManager nhằm kiểm tra thời lượng kể từ khi tải tệp tham chiếu quảng cáo. Tiếp theo, hãy dùng phương thức đó để kiểm tra xem quảng cáo có còn hợp lệ không. Cập nhật phương thức AppOpenManager của bạn như sau:

/** Prefetches App Open Ads and handles lifecycle detection. */
public class AppOpenManager implements LifecycleObserver, Application.ActivityLifecycleCallbacks {
  ...
  private long loadTime = 0;

  /** Request an ad */
  public void fetchAd() {
    // Have unused ad, no need to fetch another.
    if (isAdAvailable()) {
      return;
    }

    loadCallback =
        new AppOpenAd.AppOpenAdLoadCallback() {
          /**
           * Called when an app open ad has loaded.
           *
           * @param ad the loaded app open ad.
           */
          @Override
          public void onAppOpenAdLoaded(AppOpenAd ad) {
            AppOpenManager.this.appOpenAd = ad;
            AppOpenManager.this.loadTime = (new Date()).getTime();
          }

          /**
           * Called when an app open ad has failed to load.
           *
           * @param loadAdError the error.
           */
          @Override
          public void onAppOpenAdFailedToLoad(LoadAdError loadAdError) {
            // Handle the error.
          }

        };
    AdRequest request = getAdRequest();
    AppOpenAd.load(
        myApplication, AD_UNIT_ID, request, AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, loadCallback);
  }
  ...

  /** Utility method to check if ad was loaded more than n hours ago. */
  private boolean wasLoadTimeLessThanNHoursAgo(long numHours) {
    long dateDifference = (new Date()).getTime() - this.loadTime;
    long numMilliSecondsPerHour = 3600000;
    return (dateDifference < (numMilliSecondsPerHour * numHours));
  }

  /** Utility method that checks if ad exists and can be shown. */
  public boolean isAdAvailable() {
    return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4);
  }
}

Khởi động nguội và màn hình tải

Từ đầu đến giờ, tài liệu này giả định rằng bạn chỉ hiển thị quảng cáo khi mở ứng dụng vào lúc người dùng đưa ứng dụng của bạn lên nền trước khi ứng dụng bị tạm ngưng trong bộ nhớ. "Khởi động nguội" xảy ra khi người dùng chạy ứng dụng của bạn nhưng trước đó, ứng dụng không bị tạm ngưng trong bộ nhớ.

Một ví dụ về khởi động nguội là khi người dùng mở ứng dụng của bạn lần đầu tiên. Trong trường hợp khởi động nguội, quảng cáo khi mở ứng dụng chưa được tải trước lần nào nên chưa sẵn sàng để hiển thị ngay lập tức. Một tình huống có thể xảy ra trong khoảng thời gian từ khi bạn yêu cầu quảng cáo cho đến khi nhận được quảng cáo (gọi là độ trễ), đó là người dùng vừa mới sử dụng ứng dụng của bạn trong chốc lát thì một quảng cáo không phù hợp đột ngột xuất hiện khiến họ bị bất ngờ. Bạn nên tránh làm như vậy vì điều này sẽ tạo ra trải nghiệm kém cho người dùng.

Nếu dùng quảng cáo khi mở ứng dụng vào lúc khởi động nguội, thì bạn nên dùng màn hình tải để tải các tài sản của trò chơi hoặc ứng dụng đó. Đồng thời, bạn chỉ nên hiển thị quảng cáo từ màn hình tải. Bạn đừng hiển thị quảng cáo nếu ứng dụng đã tải xong và đã đưa người dùng tới nội dung chính của ứng dụng.

Các phương pháp hay nhất

Quảng cáo khi mở ứng dụng giúp bạn kiếm tiền từ màn hình tải của ứng dụng, khi ứng dụng chạy lần đầu và khi chuyển đổi ứng dụng. Tuy nhiên, bạn cần ghi nhớ các phương pháp hay nhất để làm cho người dùng thích sử dụng ứng dụng của bạn. Tốt nhất là bạn nên:

  • Hiển thị quảng cáo khi mở ứng dụng đầu tiên sau khi người dùng đã sử dụng ứng dụng của bạn vài lần.
  • Hiển thị quảng cáo khi mở ứng dụng trong thời gian người dùng chờ ứng dụng của bạn tải.
  • Nếu bạn có màn hình tải trong quảng cáo khi mở ứng dụng và màn hình tải đó đã tải xong trước khi quảng cáo bị đóng, thì bạn nên đóng màn hình tải theo phương thức onAdDismissedFullScreenContent().

Ví dụ trên GitHub

  • Ví dụ về Quảng cáo khi mở ứng dụng: Java | Kotlin