アプリのマネタイズの基本といえば、やはり広告。AndroidアプリならまずAdMobが候補に挙がりますよね。広告タイプの違いと実装方法をコードを見ながら押さえましょう。
AdMobはグーグルによるモバイル広告プラットホームであり、開発者はAdMobを使ってアプリ内の広告から収益を得られます。AdMobによってバナー広告、インタースティシャル広告、ビデオ広告、ネイティブのUIコンポーネントと一体化したネイティブ広告などさまざまな種類の広告が提供されます。
AdMobはGoogle Mobile Ads SDKを使って収益を最大化でき、グーグルの広告ソリューションによって大規模なビジネスを実現します。本記事はAdMobのアプリへの組み込みに焦点をあてますが、その前に広告の実装方法に関するベストプラクティスやポリシーを理解しておいたほうが理解が進みます。バナー広告やインタースティシャル広告についてのAdMob YouTubeビデオの視聴をおすすめします。
AdMobの開始
AdMobサービスにサインアップします。
- AdMobのWebサイトを開く
- 「Monetize」タブをクリック
- 「Monetize new app」をクリック
- 広告フォーマットをBanner(バナー)、Interstitial(インタースティシャル)、Rewarded interstitial(リワードインタースティシャル)、Native(ネイティブ)から選択
- 「Ad unit name」を入力
- 広告からFirebaseへのリンクを選択可能。ただし、今回はこのステップは省略
さまざまな広告フォーマットをアプリに追加できます。本記事でこれから説明するサンプルアプリのために、3つの異なる広告フォーマット、バナー、インタースティシャル、ネイティブ広告を作成しました。新しい広告をアプリに追加するには、タブを開いてアプリを選択します。
構成
空のアクティビティを使用して新しいAndroidプロジェクトを作成し、以下のbuild.gradle(Module: app)への依存オブジェクトを追加します。
dependencies {
compile 'com.google.android.gms:play-services:9.4.0'
}
res/values/strings.xmlでユニットIDを追加します。このケースではIDは以下のようになります。
<!--Ad unit ID-->
<string name="admob_banner_ad">ca-app-pub-3306270630045532/9042995609</string>
<string name="admob_interstitial_ad">ca-app-pub-3306270630045532/1519728802</string>
<string name="admob_native_ad">ca-app-pub-3306270630045532/4473195204</string>
AndroidManifest.xmlにGoogle Mobile Adsで必要なパーミッションを追加します。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Androidアプリへの組み込み広告
このあとは、生成した広告をAndroidアプリに組み込む方法に関する3つの事例です。それぞれの事例はスタンドアローンのアプリに組み込み可能ですが、本記事のGitHubリポジトリでは別のフラグメントとして同様のプロセスの広告を追加しました。
バナー広告
本項ではバナーの追加およびイベント処理に焦点をあてます。Androidプロジェクトにバナーを追加するのは、ほかの広告タイプの組み込みに比べるともっとも簡単な選択肢です。レイアウトファイルで適切な場所を選択し、以下のコードスニペットを追加します。これがActivityのレイアウトファイルの例になります。
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
ads:adSize="SMART_BANNER"
ads:adUnitId="@string/admob_banner_ad">
</com.google.android.gms.ads.AdView>
広告サイズをSMART_BANNERとして指定するとバナーの横幅が画面サイズにフィットするように設定されます。AdMobではさまざまなサイズが利用できますので、詳細についてはこのドキュメントを参照してください。また以下のように、レイアウトファイルのLayoutコンテナに広告用に使用するネームスペースを追加してください。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:ads="http://schemas.android.com/apk/res-auto">
...
<com.google.android.gms.ads.AdView>
...
</com.google.android.gms.ads.AdView>
</RelativeLayout>
すでにAdViewをレイアウトファイルに追加したので、コンテンツをその中へロードする必要があります。広告を表示するActivityクラスで、以下のグローバルインスタンスを生成します。
private AdView adView;
アクティビティのonCreate()メソッドで以下のコードスニペットを追加します。
// Initialize the Mobile Ads SDK.
MobileAds.initialize(this, getResources().getString(R.string.admob_banner_ad));
adView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder()
.build();
adView.loadAd(adRequest);
開発中に広告をテストする場合はテストデバイスとしてAdRequestを指定するのがおすすめです。ただし、本記事ではテストデバイスは指定していません。
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice("DEVICE ID")
.build();
広告の管理における重要なポイントの1つはActivityのライフサイクルメソッドであり、以下のメソッドをMainActivityクラスに追加する必要があります。
@Override
public void onPause() {
super.onPause();
if (adView != null) adView.pause();
}
@Override
public void onResume() {
super.onResume();
if (adView != null) adView.resume();
}
@Override
public void onDestroy() {
super.onDestroy();
if (adView != null) adView.destroy();
}
Androidプロジェクトを実行して広告の表示を確認します。
広告イベント
広告の管理におけるもう1つの重要なポイントはライフサイクルイベントです。広告イベントのリストにはloading、opening、closing、failed to load、AdLeftApplicationなどのイベントが含まれます。監視するライフサイクルイベントを選択可能であり、onCreateで発生するすべてのイベントのリスナーを以下のコードでセットアップします。
adView.setAdListener(new AdListener() {
@Override
public void onAdClosed() {
super.onAdClosed();
//user returns to the app after tapping on an ad.
}
@Override
public void onAdFailedToLoad(int i) {
super.onAdFailedToLoad(i);
//Ad request fails.
}
@Override
public void onAdLeftApplication() {
super.onAdLeftApplication();
//User left the app.
}
@Override
public void onAdOpened() {
super.onAdOpened();
//Ad displayed on the screen.
}
@Override
public void onAdLoaded() {
super.onAdLoaded();
//Ad finishes loading.
}
});
これらのイベントはバナー広告でもインタースティシャル広告でも動作します。
インタースティシャル広告
インタースティシャル広告とはアプリのインターフェイス全体を覆う全画面広告のことです。その名のとおり、広告の全画面表示によって、ユーザーとアプリのインターフェイスが阻害されます。そのため、インタースティシャル広告を表示するタイミングには注意を払う必要があります。アプリが遷移するタイミングで広告を表示するのは良い方法ですが、頻繁に広告を表示するのはあまり良くありません。インタースティシャル広告はロードするためのレイアウトを持っているわけではなく、Javaコードでロードします。
MainActivityにインタースティシャル広告を追加するためのグローバルインスタンスを生成します。
private InterstitialAd interstitialAd;
インタースティシャル広告を表示するには以下の関数を呼び出します。
private void loadInterstitialAd() {
interstitialAd = new InterstitialAd(this);
interstitialAd.setAdUnitId(getResources().getString(R.string.admob_interstitial_ad));
AdRequest adRequest = new AdRequest.Builder()
.build();
interstitialAd.loadAd(adRequest);
interstitialAd.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
super.onAdLoaded();
interstitialAd.show();
}
});
}
インタースティシャル広告は多くの帯域幅を使用し、ロード時間も必要だということに留意してください。そのため、ロード処理が完了したあとに広告を表示することが重要です。インタースティシャル広告とともに前に説明したライフサイクルイベントを使用して、特定の広告イベントを監視できます。
ネイティブ広告
ネイティブ広告はアプリのコンテンツに合わせて広告をカスタマイズするとても良い方法です。ネイティブ広告は広告ビューのCSSテンプレートです。AdMobはネイティブ広告を実装する2つの異なる方法、「Native Ads Express」と「Native Ads Advanced」を提供しています。
Native Ads Expressは事前に定義されたビューおよび広告のテンプレートをベースにしたAdMobパネル内で生成されたCSSテンプレートです。広告プレゼンテーションを完全に制御したいと考える開発者向けに、AdMobではNative Ads Advancedが提供されています。
以下のネイティブ広告の事例では、Express Adsを使用して作業します。Androidプロジェクト内でネイティブ広告を追加するプロセスはバナー広告と同様であり、次の項の主なポイントはそのアイテムとして含まれるネイティブ広告を使用してRecyclerViewをビルドすることです。
RecyclerViewのビルドにはRecyclerView.Adapter、RecyclerView.ViewHolder、RecyclerViewアイテム用のレイアウトファイルが必要です。広告をアプリにうまく組み込むには、アイテムのレイアウトがネイティブ広告のレイアウトのように見えるようにするのが望ましいです。この例では、以下のレイアウトを使用します。res/layout/item_layout.xmlを生成して以下の記述を追加します。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="15dp"
android:src="@android:drawable/ic_menu_gallery" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="25dp"
android:orientation="vertical">
<TextView
android:id="@+id/itemTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="4dp"
android:text="RecyclerView Item"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/itemDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="RecyclerView Item Description"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
そして、res/layout/native_ad.xmlには以下を記述します。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.gms.ads.NativeExpressAdView
android:id="@+id/nativeAdView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adSize="340x100"
ads:adUnitId="@string/admob_native_ad">
</com.google.android.gms.ads.NativeExpressAdView>
</LinearLayout>
MainActivityレイアウトファイル内でRecyclerViewレイアウトを追加します。
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
RecyclerViewアダプターの設定
RecyclerViewがコンテンツを表示するにはアダプターとViewHolderが必要です。RV_Adapterと呼ばれる新しいJavaクラスを生成し、以下のコードを追加します。
public class RV_Adapter extends RecyclerView.Adapter<ViewHolder> {
private static final int ITEM = 0;
private static final int NATIVE_AD = 1;
int[] viewTypes;
List<Data> list = Collections.emptyList();
public RV_Adapter(List<Data> list, int[] viewTypes) {
this.list = list;
this.viewTypes = viewTypes;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//Inflate the layout, initialize the View Holder
View v;
if (viewType == ITEM) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
ViewHolder holder = new ItemViewHolder(v);
return holder;
} else if (viewType == NATIVE_AD) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.native_ad, parent, false);
ViewHolder holder = new AdViewHolder(v);
return holder;
}
return null;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
if (viewHolder.getItemViewType() == ITEM) {
ItemViewHolder holder = (ItemViewHolder) viewHolder;
//populate the RecyclerView
//holder.title.setText(list.get(position).getTitle());
//holder.description.setText(list.get(position).getDescription());
} else if (viewHolder.getItemViewType() == NATIVE_AD) {
AdViewHolder holder = (AdViewHolder) viewHolder;
//Load the Ad
AdRequest request = new AdRequest.Builder()
.build();
holder.adView.loadAd(request);
}
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
@Override
public int getItemViewType(int position) {
return viewTypes[position];
}
}
class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View v) {
super(v);
}
}
class ItemViewHolder extends ViewHolder {
TextView title;
TextView description;
ItemViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.itemTitle);
description = (TextView) itemView.findViewById(R.id.itemDescription);
}
}
class AdViewHolder extends ViewHolder {
NativeExpressAdView adView;
public AdViewHolder(View v) {
super(v);
adView = (NativeExpressAdView) v.findViewById(R.id.nativeAdView);
}
}
このクラスにはRecyclerView.Adapterと、異なるRecyclerViewアイテム用の3つのViewHolderクラスが含まれます。たくさんのコードが存在しますが、3つのほかのJavaクラスはこのアダプター内でのみ使用されます。それらを別々のファイルで実行しても良いですが、それぞれのクラスへの正しい参照をインポートするようにしてください。onBindViewHolder()アダプター内のRecyclerViewでネイティブ広告を読み込みます。この広告のバインドはバナー広告と類似しています。
RecyclerViewはDataオブジェクトのリストで埋まっているため、Androidプロジェクト内に以下のクラスを生成します。
public class Data {
private String title;
private String description;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
広告リストの表示
RecyclerViewにネイティブ広告を組み込むための最終ステップではMainActivity内に以下の関数を生成します。
private void initRecyclerView() {
//Create dummy data for RecyclerView
int listSize = 50;
int ITEM = 0;
int NATIVE_AD = 1;
List<Data> data = new ArrayList<>();
int[] viewTypes = new int[listSize];
for (int i = 0; i < listSize; i++) {
data.add(new Data());
//insert native ads once in five items
if (i > 1 && i % 5 == 0) {
viewTypes[i] = NATIVE_AD;
} else {
viewTypes[i] = ITEM;
}
}
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
RV_Adapter adapter = new RV_Adapter(data, viewTypes);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
この関数では50個のDataアイテムのリストを生成し、5アイテムごとにネイティブ広告を挿入します。実際のプロジェクトでは、ユーザーエクスペリエンスの低下につながるため、このように頻繁には広告を挿入しません。RecyclerViewアダプターの起動時にそのコンストラクターがIntegerの配列を渡し、広告の表示時にアダプターに通知します。MainActivityonCreate()メソッド内でこの関数を呼び出し、プロジェクトを実行します。
ターゲティング
AdMobのもう1つのすばらしい特徴は、特定のユーザーをターゲットにし、特定の条件に関する広告を表示できることです。ターゲティングの例としては特定の場所やユーザーの性別に関連する広告を表示することなどが挙げられます。ターゲットグループに基づいた広告を表示するにはAdRequest.Builder()でターゲティング仕様を指定します。
以下が場所に基づいてユーザーをターゲティングする方法の例です。
AdRequest request = new AdRequest.Builder()
.setLocation(userLocation)
.build();
性別に基づく場合は、以下のとおりです。
AdRequest request = new AdRequest.Builder()
.setGender(AdRequest.GENDER_FEMALE)
.build();
誕生日に基づく場合は、以下のとおりです。
AdRequest adRequest = new AdRequest.Builder()
.setBirthday(userBirthdayDate)
.build();
子供向けのポリシーおよびグーグルが子供向け広告コンテンツを取り扱うべきか否かに基づく場合は、以下のとおりです。
AdRequest adRequest = new AdRequest.Builder()
.tagForChildDirectedTreatment(true)
.build();
収益を上げよう
以上がAdMobを使ったAndroidアプリへの広告組み込みの基本になります。このプロセスを使うと簡単な方法ですべてのアプリに収益化の可能性を生み出します。AdMobに関してさらに詳しく知りたい場合はグーグルサポートのページを参照すると役立つヒントがあります。
※本記事はWern Anchetaが査読を担当しています。最高のコンテンツに仕上げるために尽力してくれたSitePointの査読担当者のみなさんに感謝します。
(原文:Monetizing Apps with the Google AdMob SDK)
[翻訳:市川千枝/編集:Livit]