Huawei Adsの実装方法－ネイティブ広告編

# Huawei Adsの実装方法－ネイティブ広告編
[ネイティブ広告](https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides-V5/publisher-service-native-0000001050064968-V5)はこのような広告です。

<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/8b5cb9b6-c86d-69f2-1ff6-ce198f1ae35c.png"> <img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/d2114538-a618-7e9d-a9e6-951fa4375100.png">

### Ad slot ID
[Huawei Adsの実装方法－準備編](https://qiita.com/Rei_2020/items/9f9eb35f781051eba811)の[Ad slot ID](https://qiita.com/Rei_2020/items/9f9eb35f781051eba811#ad-slot-id)をご参照ください。
オフィシャルのテスト用Ad slot IDは次の通りです。

|広告の種類|テスト用Ad slot ID|
|:---:|:---:|
|大きい静止画|testu7m3hc4gvm|
|小さい静止画|testb65czjivt9|
|動画|testy63txaom86|

### レイアウト
レイアウトは主に次のパーツで構成されています。

|パーツ|型|必須|用途|
|:---:|:---:|:---:|:---|
|ネイティブビュー|NativeView|〇|ネイティブ広告のベースのビューです。ほかのパーツはこのビューの中で実装します。|
|広告の静止画・動画|MediaView|〇|広告の静止画と動画を取り扱うパーツです。|
|タイトル|TextView|×|広告のタイトルです。タイトルがないものもあります。|
|広告ソース|TextView|×|広告のソースです。|
|行動|Button|×|バナーが押されたときの動作の説明です。たとえば、広告の情報やインストールなど|

以下はレイアウトのサンプルです。

<b>レイアウト（小）</b>

```xml:layout.xml
<com.huawei.hms.ads.nativead.NativeView
    android:id="@+id/native_small_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:layout_marginTop="10dp"
    android:background="#FFFFFF"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/background"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:orientation="vertical">

        <com.huawei.hms.ads.nativead.MediaView
            android:id="@+id/ad_media"
            android:layout_width="75dp"
            android:layout_height="50dp"
            android:layout_marginStart="24dp"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:background="#8BC34A" />

        <RelativeLayout
            android:id="@+id/center_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="107dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="48dp"
            android:layout_marginBottom="8dp"
            android:background="#FFFFFF">

            <TextView
                android:id="@+id/ad_title"
                android:layout_width="match_parent"
                android:layout_height="34dp"
                android:layout_marginBottom="16dp"
                android:alpha="1"
                android:textColor="#000000"
                android:textSize="13sp" />

            <TextView
                android:id="@+id/ad_source"
                android:layout_width="wrap_content"
                android:layout_height="14dp"
                android:layout_marginTop="36dp"
                android:alpha="0.6"
                android:maxWidth="132dp"
                android:textColor="#666666"
                android:textSize="9sp" />

            <TextView
                android:id="@+id/ad_flag"
                android:layout_width="16dp"
                android:layout_height="14dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="36dp"
                android:layout_toEndOf="@+id/ad_source"
                android:background="@drawable/native_flag_rounded_corners_shape"
                android:gravity="center"
                android:text="ad"
                android:textColor="#FFFFFF"
                android:textSize="8sp"
                android:textStyle="bold" />

            <Button
                android:id="@+id/ad_call_to_action"
                android:layout_width="44dp"
                android:layout_height="@dimen/hiad_16_dp"
                android:layout_alignParentEnd="true"
                android:layout_marginTop="34dp"
                android:background="@drawable/native_button_rounded_corners_shape"
                android:textColor="#FFFFFF"
                android:textSize="6sp" />
        </RelativeLayout>
    </RelativeLayout>
</com.huawei.hms.ads.nativead.NativeView>
```

<b>レイアウト（大）</b>

```xml:layout.xml
<com.huawei.hms.ads.nativead.NativeView
    android:id="@+id/native_video_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:background="#FFFFFF"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/background"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.huawei.hms.ads.nativead.MediaView
            android:id="@+id/ad_media"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <RelativeLayout
            android:id="@+id/left_bottom_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/ad_media">

            <TextView
                android:id="@+id/ad_title"
                android:layout_width="180dp"
                android:layout_height="19dp"
                android:layout_marginStart="24dp"
                android:layout_marginTop="16dp"
                android:alpha="1"
                android:textColor="#000000"
                android:textSize="13sp" />

            <TextView
                android:id="@+id/ad_source"
                android:layout_width="wrap_content"
                android:layout_height="19dp"
                android:layout_below="@id/ad_title"
                android:layout_marginStart="24dp"
                android:layout_marginTop="2dp"
                android:layout_marginBottom="16dp"
                android:alpha="0.6"
                android:maxWidth="158dp"
                android:textColor="#666666"
                android:textSize="12sp" />

            <TextView
                android:id="@+id/ad_flag"
                android:layout_width="20dp"
                android:layout_height="14dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="40dp"
                android:layout_toEndOf="@+id/ad_source"
                android:background="@drawable/native_flag_rounded_corners_shape"
                android:gravity="center"
                android:text="@string/ad_flag"
                android:textColor="#FFFFFF"
                android:textSize="8sp"
                android:textStyle="bold" />
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/right_bottom_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/ad_media"
            android:layout_alignParentEnd="true">

            <Button
                android:id="@+id/ad_call_to_action"
                android:layout_width="72dp"
                android:layout_height="26dp"
                android:layout_alignParentEnd="true"
                android:layout_marginTop="23dp"
                android:layout_marginEnd="52dp"
                android:layout_marginBottom="23dp"
                android:background="@drawable/native_button_rounded_corners_shape"
                android:textColor="#FFFFFF"
                android:textSize="10sp" />
        </RelativeLayout>
    </RelativeLayout>
</com.huawei.hms.ads.nativead.NativeView>
```

<b>その他のパーツ</b>

```xml:native_flag_rounded_corners_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#CCCCCC" />

    <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="1dp" />

    <corners
        android:bottomLeftRadius="2dp"
        android:bottomRightRadius="2dp"
        android:topLeftRadius="2dp"
        android:topRightRadius="2dp" />
</shape>
```

```xml:native_button_rounded_corners_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#214EF3" />

    <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="1dp" />

    <corners
        android:bottomLeftRadius="20dp"
        android:bottomRightRadius="20dp"
        android:topLeftRadius="20dp"
        android:topRightRadius="20dp" />
</shape>
```

### Activity/Fragment
ActivityまたはFragmentに、次の種類のソースコードを入れます。

<b>広告設定</b>

```kotlin
// 動画広告の設定
val videoConfiguration = VideoConfiguration.Builder()
    // 動画広告の場合、ミュート状態で開始
    .setStartMuted(true)
    .build()

// 広告の設定
val adConfiguration = NativeAdConfiguration.Builder()
    // 動画広告の設定
    .setVideoConfiguration(videoConfiguration)
    // true: デフォルトの広告非表示ボタンを使わない, false: デフォルトの広告非表示ボタンを使う
    .setRequestCustomDislikeThisAd(false)
    // "i" または "x"の表示位置
    .setChoicesPosition(NativeAdConfiguration.ChoicesPosition.BOTTOM_RIGHT)
    .build()
```

<b>広告操作</b>

```kotlin
// ネイティブ広告のリスナー
val nativeAdLoadedListener = object : NativeAd.NativeAdLoadedListener {
    // ネイティブ広告のロードが完了したとき呼び出される
    override fun onNativeAdLoaded(nativeAd: NativeAd?) {
        nativeAd?.let {
            // 動画広告のコールバックを設定する
            it.videoOperator.videoLifecycleListener = object : VideoOperator.VideoLifecycleListener() {
                override fun onVideoStart() {}
                override fun onVideoPlay() {}
                override fun onVideoPause() {}
                override fun onVideoEnd() {}
                override fun onVideoMute(var1: Boolean) {}
            }

            // 広告の×ボタンを押したときのコールバックを設定する
            it.setDislikeAdListener {
                // たとえば、広告のビューを外す
            }

            // ネイティブ広告のデータをcom.huawei.hms.ads.nativead.NativeViewに設定する

            // addView()でcom.huawei.hms.ads.nativead.NativeViewをレイアウトに追加する
        }
    }
}

// 広告の各種イベントのコールバック
val adListener = object : AdListener() {
    // 広告のロードが完了したとき呼び出される
    override fun onAdLoaded() {
        super.onAdLoaded()
        binding.btnLoad.isEnabled = true
    }

    // 広告のロードが失敗したとき
    override fun onAdFailed(errorCode: Int) {
        super.onAdFailed(errorCode)
        binding.btnLoad.isEnabled = true
    }

    // その他のイベント
    override fun onAdClosed(){}
    override fun onAdLeave(){}
    override fun onAdOpened(){}
    override fun onAdClicked(){}
    override fun onAdImpression(){}
}
```

<b>広告読込</b>

```kotlin
val builder = NativeAdLoader.Builder(context, getAdId())
    .setNativeAdLoadedListener(nativeAdLoadedListener)
    .setAdListener(adListener)

val nativeAdLoader = builder.setNativeAdOptions(adConfiguration).build()
nativeAdLoader.loadAds(AdParam.Builder().build(), "{広告の上限数}")

```

<b>広告表示</b>

com.huawei.hms.ads.nativead.NativeViewに、ネイティブ広告データを設定する

```kotlin
// レイアウト（小）やレイアウト（大）などのレイアウト
val binding = DataBindingUtil.inflate<XXXXXXXXXBinding>(
            LayoutInflater.from(
                context
            ), R.layout.xxxxxxxxxxx, null, false
        )
val nativeView = {com.huawei.hms.ads.nativead.NativeView要素}
nativeView.titleView = binding.adTitle
nativeView.mediaView = binding.adMedia
nativeView.adSourceView = binding.adSource
nativeView.callToActionView = binding.adCallToAction

nativeView.mediaView.setMediaContent(nativeAd.mediaContent)

val textView: TextView? = nativeView.adSourceView as? TextView
nativeAd.adSource?.let{ adSource ->
    textView?.text = adSource
}
textView?.visibility = if (null != nativeAd.adSource) View.VISIBLE else View.INVISIBLE

val button: Button? = nativeView.callToActionView as? Button
nativeAd.callToAction?.let { callToAction ->
    button?.text = callToAction
}
button?.visibility = if (null != nativeAd.callToAction) View.VISIBLE else View.INVISIBLE

nativeView.setNativeAd(nativeAd)

// 表示するターゲットのビューにをaddView(binding.root)で追加する
```

# Huawei Adsシリーズ
- [Huawei Adsの機能のまとめ](https://qiita.com/Rei_2020/items/87804f2057d4b143fc12)
- [Huawei Adsの実装方法－準備編](https://qiita.com/Rei_2020/items/9f9eb35f781051eba811)
- [Huawei Adsの実装方法－広告用識別子（OAID）編](https://qiita.com/Rei_2020/items/f5446a2bbbb4d5d3df67)
- [Huawei Adsの実装方法－インストールリファラー編](https://qiita.com/Rei_2020/items/977eabb3a514ba5c2476)
- [Huawei Adsの実装方法－バナー広告編](https://qiita.com/Rei_2020/items/308ebf626c1423a7cb1f)
- [Huawei Adsの実装方法－ネイティブ広告編](https://qiita.com/Rei_2020/items/f60976c23c1268261d5f)
- [Huawei Adsの実装方法－リワード広告編](https://qiita.com/Rei_2020/items/06744db6572c1603b0bd)
- [Huawei Adsの実装方法－インタースティシャル広告編](https://qiita.com/Rei_2020/items/3c9d9a19861a2d139737)
- [Huawei Adsの実装方法－スプラッシュ広告編](https://qiita.com/Rei_2020/items/5a138945d7b343602df1)

# GitHub
HMS Ads Kit Demo : [https://github.com/Rei2020GitHub/MyPublicProject/tree/master/AdsDemo](https://github.com/Rei2020GitHub/MyPublicProject/tree/master/AdsDemo)

# 参考
* HMS：[https://developer.huawei.com/consumer/jp/](https://developer.huawei.com/consumer/jp/)
* HMS Ads Kitの紹介：[https://developer.huawei.com/consumer/jp/hms/huawei-adskit/](https://developer.huawei.com/consumer/jp/hms/huawei-adskit/)
* HMS Ads Kitのドキュメント：[https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/publisher-service-introduction-0000001070671805](https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/publisher-service-introduction-0000001070671805)
* HUAWEI Ads Publisher Service：[https://developer.huawei.com/consumer/jp/monetize/](https://developer.huawei.com/consumer/jp/monetize/)
* HUAWEI Ads Publisher Serviceのドキュメント：[https://developer.huawei.com/consumer/jp/doc/distribution/monetize/advantage-0000001051201913](https://developer.huawei.com/consumer/jp/doc/distribution/monetize/advantage-0000001051201913)
* Huawei Developers：[https://forums.developer.huawei.com/forumPortal/en/home](https://forums.developer.huawei.com/forumPortal/en/home)
* Facebook Huawei Developersグループ：[https://www.facebook.com/Huaweidevs/](https://www.facebook.com/Huaweidevs/)