［Android］AdMob Native Adを使って広告を表示する

# はじめに

[AdMob Native Advanced Ads in an Android Feed](https://codelabs.developers.google.com/codelabs/admob-native-advanced-feed-android/#0)を参考にしながら、
AdMob NativeAdの広告を表示するAndroidアプリを実装してみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/c9ed2b12-730f-3cd6-4e06-7cfea34aa44b.png)

# 1. アプリIDを作成する

AdMobの機能を利用するためにはアプリIDを割り当ててもらう必要があります。
アプリIDは[AdMob](https://admob.google.com/home/)にて次の手順で作成することができます。

1. [AdMob](https://admob.google.com/home/)にアクセスする。
2. 「Sign Up」でアカウントを作成し、「Sign In」する。
3. 「アプリ」->「アプリを追加」をクリックする。
4. 「Google PlayやApp Storeでアプリを公開していますか？」で「いいえ」を選択する。
5. 「アプリ名」に「AdMobUnifiedNativeAdTest」、「プラットフォーム」を「Android」で「追加」をクリックする。
6. 表示された「アプリID」をコピーし控えておく

# 2. NativeAdの広告ユニットIDを作成する

広告ユニットIDは、AdMobで表示する広告ユニットに割り当てられるIDです。
この広告ユニットIDは広告を読み込む際に利用しますので、次の手順で作成します。

1. アプリIDを作成した後、「広告ユニットの作成」をクリックする。
2. 「広告フォーマット」の選択で「ネイティブ アドバンス」を選択する。
3. 「広告ユニット名」に任意の名称を入力し、「広告ユニット」を作成をクリックする。
4. 表示された「広告ユニットID」をコピーし控えておく

# 3. Mobile Ads SDK を追加する

Androidプロジェクトを作成した後、まずはMobile Ads SDKを追加します。
Mobile Ads SDKはUnifiedNativeAdを実装する際に必要となるライブラリです。
次のようにbuild.gradle(app)に記述を追加することで追加できます。

```groovy:build.gradle(app)
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.google.android.gms:play-services-ads:18.2.0' //  Add Line
}
```

# 4. AndroidManifest.xmlにアプリIDを記述する

AdMobを使うにはAndroidManifest.xmlにアプリIDを記述する必要があります。
次にようにAndroidManifest.xmlにアプリを記述してください。

```xml:AndroidManifest.xml
<manifest>
    <application>
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
    </application>
</manifest>
```

# 5. Mobile Ads SDKを初期化する

Mobile Ads SDKを使うには初期化が必要になります。
次のようにMainActivity.ktに初期化処理を記述してください。

```kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        MobileAds.initialize(this) {} // Add Line
    }
}
```

# 6. Native Adを表示するビューを作成する

Native Adを表示するビューですが、[「Native Template」](https://developers.google.com/admob/android/native/templates)を使って簡単に実装できますが、
今回は柔軟にレイアウトをカスタマイズできるように「Native Advanced」を使って実装してみます。
Native Advancedで実装するには次のようにUnifiedNativeAdViewをルートとしたビューを作成する必要があります。

## Design
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/27e0f3d0-bf7c-1347-a5a7-4925a6a409db.png)

## XML
```xml:unified_nativead_view
<com.google.android.gms.ads.formats.UnifiedNativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ad_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:foreground="?selectableItemBackground"
            android:background="#ffffff"
            android:minHeight="50dp"
            android:orientation="vertical">

        <TextView
                android:id="@+id/ad_attribution"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="left"
                android:textColor="#FFFFFF"
                android:textSize="12sp"
                android:text="Ad"
                android:background="#FFCC66"
                android:width="15dp"
                android:height="15dp" />

        <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingLeft="20dp"
                android:paddingRight="20dp"
                android:paddingTop="3dp">

            <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">

                <ImageView
                        android:id="@+id/ad_icon"
                        android:layout_width="40dp"
                        android:layout_height="40dp"
                        android:adjustViewBounds="true"
                        android:paddingBottom="5dp"
                        android:paddingRight="5dp"
                        android:paddingEnd="5dp" />

                <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical">

                    <TextView
                            android:id="@+id/ad_headline"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:textColor="#0000FF"
                            android:textSize="16sp"
                            android:textStyle="bold" />

                    <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content">

                        <TextView
                                android:id="@+id/ad_advertiser"
                                android:layout_width="wrap_content"
                                android:layout_height="match_parent"
                                android:gravity="bottom"
                                android:textSize="14sp"
                                android:textStyle="bold" />

                        <RatingBar
                                android:id="@+id/ad_stars"
                                style="?android:attr/ratingBarStyleSmall"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:isIndicator="true"
                                android:numStars="5"
                                android:stepSize="0.5" />
                    </LinearLayout>

                </LinearLayout>
            </LinearLayout>

            <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                <TextView
                        android:id="@+id/ad_body"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginRight="20dp"
                        android:layout_marginEnd="20dp"
                        android:textSize="12sp" />

                <com.google.android.gms.ads.formats.MediaView
                        android:id="@+id/ad_media"
                        android:layout_gravity="center_horizontal"
                        android:layout_width="250dp"
                        android:layout_height="50dp"
                        android:layout_marginTop="5dp" />

                <LinearLayout
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="end"
                        android:orientation="horizontal"
                        android:paddingBottom="10dp"
                        android:paddingTop="10dp">

                    <TextView
                            android:id="@+id/ad_price"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:paddingLeft="5dp"
                            android:paddingStart="5dp"
                            android:paddingRight="5dp"
                            android:paddingEnd="5dp"
                            android:textSize="12sp" />

                    <TextView
                            android:id="@+id/ad_store"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:paddingLeft="5dp"
                            android:paddingStart="5dp"
                            android:paddingRight="5dp"
                            android:paddingEnd="5dp"
                            android:textSize="12sp" />

                    <Button
                            android:id="@+id/ad_call_to_action"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:textSize="12sp" />
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</com.google.android.gms.ads.formats.UnifiedNativeAdView>
```

# 7. Native Adを表示するコンテナを用意する

unified_nativead_viewをinflateするコンテナを用意します。
次のようにactivity_main.xmlにFrameLayoutを用意し、
MainActivityにてFrameLayoutを利用できるようにします。

```xml:main_activity.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/nativead_container"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

# 8. UnifiedNativeViewを生成するBuilderを作る

UnifiedNativeAdViewを生成していきます。
次のようにMainActivity.ktにてUnifiedNativeAdを生成します。

💡 AdLoader.Builderで広告を生成するのですが、先ほど控えておいた広告ユニットIDを利用します。

```kotlin:MainActivity.kt
  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        MobileAds.initialize(this) {}

        val builder = AdLoader.Builder(this, "広告ユニットID")
        builder.forUnifiedNativeAd { nativeAd ->
            val adView = layoutInflater.inflate(R.layout.unified_nativead_view, null)
            val container = findViewById<FrameLayout>(R.id.nativead_container)
            container.removeAllViews()
            container.addView(adView)
        }
    }
```

# 9. 取得した広告をViewに表示する

取得した広告をViewに表示します。
作成したunified_natived_viewの各ビューに対して広告情報をセットします。

今回はわかりやすくするためにfindViewByIdを何度も呼び出していますが、
実際に使うときにはViewHolderなどを使って実装してください。


```kotlin:MainActivity.kt
         builder.forUnifiedNativeAd { nativeAd ->
            val view = layoutInflater.inflate(R.layout.unified_nativead_view, null)
            val container = findViewById<FrameLayout>(R.id.nativead_container)

            view.findViewById<TextView>(R.id.ad_headline).text = nativeAd.headline
            view.findViewById<TextView>(R.id.ad_body).text = nativeAd.body
            view.findViewById<TextView>(R.id.ad_call_to_action).text = nativeAd.callToAction

            val icon = nativeAd.icon
            if (icon == null) {
                view.findViewById<ImageView>(R.id.ad_icon).visibility = View.INVISIBLE
            } else {
                view.findViewById<ImageView>(R.id.ad_icon).setImageDrawable(icon.drawable)
                view.findViewById<ImageView>(R.id.ad_icon).visibility = View.VISIBLE
            }

            if (nativeAd.price == null) {
                view.findViewById<TextView>(R.id.ad_price).visibility = View.INVISIBLE
            } else {
                view.findViewById<TextView>(R.id.ad_price).visibility = View.VISIBLE
                view.findViewById<TextView>(R.id.ad_price).text = nativeAd.price
            }

            if (nativeAd.store == null) {
                view.findViewById<TextView>(R.id.ad_store).visibility = View.INVISIBLE
            } else {
                view.findViewById<TextView>(R.id.ad_store).visibility = View.VISIBLE
                view.findViewById<TextView>(R.id.ad_store).text = nativeAd.store
            }

            if (nativeAd.starRating == null) {
                view.findViewById<RatingBar>(R.id.ad_stars).visibility = View.INVISIBLE
            } else {
                view.findViewById<RatingBar>(R.id.ad_stars).rating = nativeAd.starRating.toFloat()
                view.findViewById<RatingBar>(R.id.ad_stars).visibility = View.VISIBLE
            }

            if (nativeAd.advertiser == null) {
                view.findViewById<TextView>(R.id.ad_advertiser).visibility = View.INVISIBLE
            } else {
                view.findViewById<TextView>(R.id.ad_advertiser).text = nativeAd.advertiser
                view.findViewById<TextView>(R.id.ad_advertiser).visibility = View.VISIBLE
            }

            val adView = view as? UnifiedNativeAdView
            adView?.setNativeAd(nativeAd)

            container.removeAllViews()
            container.addView(view)
        }

```

# 10. BuilderからLoaderを作り読み込みを開始する

先程作成したBuilderからLoaderを生成します。
そのLoaderで次のようにloadAd(...)を実行すると広告の読み込みが開始します。

```Kotlin:MainActivity.kt
  override fun onCreate(savedInstanceState: Bundle?) {
                  ︙
        MobileAds.initialize(this) {
            val loader = builder.build()
            loader.loadAd(AdRequest.Builder().build())
        }
                  ︙
  }
```

# おわりに

ドキュメントは公式の情報も散らかっててわかりづらいですが。
AdMob NativeAdの利用はわかれば簡単だと思います。
次に作成したサンプルコードを置いておきますので何かあればご利用ください。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/e7bd19fc-9449-b3de-0d9b-37e80c5b17c8.png) | [Kaleidot725/android-mylab/AdMobNativeAdvancedAds](https://github.com/kaleidot725/android-mylab/tree/master/AdMobNativeAdvancedAds) |
| ------- | ---------------------------------------------------------------------- |

# 参考
* [アプリID](https://support.google.com/admob/answer/6232340?hl=ja)
* [広告ユニットID](https://support.google.com/admob/answer/7356431?hl=ja)
* [Get Started | Android | Google Developers](https://developers.google.com/admob/android/quick-start)
* [Native Advanced | Android | Google Developers](https://developers.google.com/admob/android/native/advanced)