# Android SDK ネイティブ広告

# はじめに

開発環境としてAndroid Studioを利用し、インストール後の各種設定は準備されていることを前提にした手順となります。

# 対応バージョン

  • Android 5.0以降(API Level 21)

# 導入の流れ

  1. SDKをダウンロードします
  2. プロジェクトにSDKを追加します
  3. AndroidManifest.xmlの設定を行います
  4. Google Play Servicesの設定を行います
  5. 例を参考に広告表示の実装を行います
  6. proguardの設定を行います

# 1. SDKをダウンロードする ~ 4. Google Play Servicesを設定する

Android SDK Getting Started / バナー広告からご確認ください。

# 5. 広告表示を実装する

start()を行う前に、ネイティブ広告オブジェクトをdelegateメソッドで取得するためのsetUsePartsResponse()の設定を行います。

ネイティブ広告オブジェクトが取得できた場合、Listenerメソッドの以下が呼び出されます。

override fun onReceiveAd(nativeAd: Any)

nativeAdからネイティブ広告オブジェクトが取得できます。
ネイティブ広告オブジェクトはcom.socdm.d.adgeneration.nativead.ADGNativeAdクラスです。

Object型からADGNativeAdへキャストし、クラス判定を行ってからアクセスしてください。
ADGNativeAdからネイティブ広告パーツを取得するメソッドは以下の通りです。

要素名 メソッド
タイトル ADGNativeAd.getTitle().getText()
メイン画像(長方形画像)URL ADGNativeAd.getMainImage().getUrl()
アイコン画像(正方形画像)URL ADGNativeAd.getIconImage().getUrl()
リード文 ADGNativeAd.getDesc().getValue()
CTA(Call to action)のテキスト ADGNativeAd.getCtatext().getValue()
広告主 ADGNativeAd.getSponsored().getValue()

# 実装例

class MainActivity : AppCompatActivity() {
    private lateinit var adg: ADG
    private lateinit var adContainer: FrameLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // デバッグログ出力設定。リリース時は[必ず]falseにしてください
        ADGSettings.setDebugLogging(true)

        adg = ADG(this).apply {
            // 管理画面から払い出された広告枠ID
            locationId = "48635"
            // Listenerの設定
            adListener = AdListener()
            // リリース時は[必ず]falseにしてください
            isTestModeEnabled = true
            layoutParams = FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.WRAP_CONTENT)
        }

        /**
         * 枠サイズ
         * AdFrameSize.SP:320x50, AdFrameSize.Large:320x100,
         * AdFrameSize.Rect:300x250, AdFrameSize.Tablet:728x90,
         * AdFrameSize.Free:自由設定
         */
        adg.setAdFrameSize(ADG.AdFrameSize.FREE.setSize(300, 250))

        // ネイティブ広告パーツ取得を有効
        adg.setUsePartsResponse(true)

        // インフォメーションアイコンのデフォルト表示
        // デフォルト表示しない場合は必ずADGInformationIconViewの設置を実装してください
        adg.setInformationIconViewDefault(false)

        // HTMLテンプレートを使用したネイティブ広告を表示のためにはaddViewする必要があります
        adContainer = findViewById<FrameLayout>(R.id.ad_container)
        adContainer.addView(adg)
    }

    override fun onResume() {
        super.onResume()

        // 広告の表示
        adg.start()
    }

    override fun onPause() {
        // 広告の破棄
        adg.stop()

        super.onPause()
    }

    internal inner class AdListener : ADGListener() {
        override fun onReceiveAd() {
        }

        override fun onReceiveAd(nativeAd: Any) {
            if (nativeAd is ADGNativeAd) {
                val nativeAdView = ADGNativeAdView(this@MainActivity)
                nativeAdView.apply(nativeAd)

                // ローテーション時に自動的にViewを削除します
                adg.setAutomaticallyRemoveOnReload(mediationView)

                adContainer.addView(mediationView, LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT)
                )
            }
        }

        override fun onFailedToReceiveAd(code: ADGConsts.ADGErrorCode) {
            // ネットワーク不通/エラー多発/広告レスポンスなし 以外はリトライしてください
            when (code) {
                ADGConsts.ADGErrorCode.EXCEED_LIMIT,
                ADGConsts.ADGErrorCode.NEED_CONNECTION,
                ADGConsts.ADGErrorCode.NO_AD -> {}
                else -> adg.start()
            }
        }
    }
}

ネイティブ広告デザイン例

  • 作成される広告イメージ
  • アプリに応じてカスタマイズください(画像ロード処理の非同期化など)。
  • レイアウトファイルはサンプルを参照してください。 https://github.com/AdGeneration/ADG-Android-SDK/tree/master/Samples
class ADGNativeAdView : RelativeLayout {

    private var activity: Activity? = null
    private lateinit var container: RelativeLayout
    private lateinit var iconImageView: ImageView
    private lateinit var titleLabel: TextView
    private lateinit var descLabel: TextView
    private lateinit var mediaViewContainer: FrameLayout
    private lateinit var sponsoredLabel: TextView
    private lateinit var CTALabel: TextView

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init(context, attrs, defStyleAttr, 0)
    }

    @TargetApi(21)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
        init(context, attrs, defStyleAttr, defStyleRes)
    }

    private fun init(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) {
        if (context is Activity) {
            activity = context
        }
        val layout = LayoutInflater.from(context).inflate(R.layout.adg_nativead_view, this)
        container = layout.findViewById(R.id.adg_nativead_view_container)
        iconImageView = layout.findViewById(R.id.adg_nativead_view_icon)
        titleLabel = layout.findViewById(R.id.adg_nativead_view_title)
        titleLabel.text = ""
        descLabel = layout.findViewById(R.id.adg_nativead_view_desc)
        descLabel.text = ""
        mediaViewContainer = layout.findViewById(R.id.adg_nativead_view_mediaview_container)
        sponsoredLabel = layout.findViewById(R.id.adg_nativead_view_sponsored)
        CTALabel = layout.findViewById(R.id.adg_nativead_view_cta)
        CTALabel.text = ""

        val borders = GradientDrawable().apply {
            setColor(Color.WHITE)
            cornerRadius = 10f
            setStroke(3, CTALabel.textColors.defaultColor)
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            CTALabel.background = borders
        } else {
            CTALabel.setBackgroundDrawable(borders)
        }
    }

    fun apply(nativeAd: ADGNativeAd) {
        nativeAd.iconImage?.url?.let {
            DownloadImageAsync(iconImageView).execute(it)
        }

        nativeAd.title?.text?.let {
            titleLabel.text = it
        }

        nativeAd.desc?.value?.let {
            descLabel.text = it
        }

        if (nativeAd.canLoadMedia()) {
            val mediaView = ADGMediaView(activity)
            mediaView.setAdgNativeAd(nativeAd)
            mediaViewContainer.addView(mediaView, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
            mediaView.load()
        }

        val infoIcon = ADGInformationIconView(context, nativeAd)
        mediaViewContainer.addView(infoIcon)

        sponsoredLabel.text = nativeAd.sponsored?.value ?: "sponsored"

        CTALabel.text = nativeAd.ctatext?.value ?: "詳しくはこちら"

        nativeAd.setClickEvent(context, container, null)
    }

    private inner class DownloadImageAsync(private val imageView: ImageView) : AsyncTask<String, Void, Bitmap?>() {
        override fun doInBackground(vararg params: String): Bitmap? {
            return try {
                val imageUrl = params[0]
                BitmapFactory.decodeStream(URL(imageUrl).openStream())
            } catch (e: Exception) {
                Log.e("Error", e.message.orEmpty())
                e.printStackTrace()
                null
            }
        }

        override fun onPostExecute(bitmap: Bitmap?) {
            imageView.setImageBitmap(bitmap)
        }
    }
}

# 注意事項

  • Activity#onResume メソッドで ADG#start メソッドを呼び、 Activity#onPause メソッドで ADG#stop メソッドを呼んでください。
  • v2.26.2から ADG#pause メソッドは非推奨になりました。代わりに ADG#stop メソッドを使用してください。
  • v2.26.2から ADG#resumeRefreshTimer メソッドは非推奨になりました。代わりに ADG#start メソッドを使用してください。
  • v2.26.2から ADG#setEnableTestMode メソッドは非推奨になりました。代わりにテストモードを有効にするときは ADG#setTestModeEnabled メソッドを使用してください。また、デバッグログを出力する場合は ADGSettings.setDebugLogging メソッドを使用してください。
  • v2.26.2から ADG#isEnableTestMode メソッドは非推奨になりました。代わりに ADG#isTestModeEnabled メソッドを使用してください。
  • v2.8.0から ADG#delegateViewManagement は非推奨となりました。
  • 代わりに ADGNativeAd#setClickEvent(Context context, View view, ADGNativeAdOnClickListener listener) および ADG#setAutomaticallyRemoveOnReload(View view) を使用してください。
  • stopを呼び出したタイミングにて、setAutomaticallyRemoveOnReloadにセットされたViewインスタンスは、親ViewからのremoveViewが呼ばれます。
  • テストではタップの確認も行ってください。
  • 画像のロードはアプリ側で実装する必要があります。
  • ADGクラスは1つの広告枠に対して1つのインスタンスを生成してください。
  • 広告枠の設定によっては各ネイティブ広告オブジェクトのパラメーターの値がnullになる場合があります。
    たとえば、GunosyAdsではCTA取得できません。接続先アドネットワーク毎に違いがございますので、nullを考慮した実装をお願いいたします。画像の縦横サイズも含め、すべてがoptionalな値です。
  • PR表記をつける等して広告であることを示してください。
  • 画像は、アスペクト比を変えず、切れることのないようしてください。
    (ImageViewのscaleTypeをFIT_CENTERに設定)
  • レスポンスにSponsoredがある場合はできる限り表示をしてください。(特定のアドネットワークではSponsoredの表示要望がございます)

# インフォメーションアイコン(オプトアウトリンク)について

※ 2016/12/8(v2.4.2)より必須項目となりました

v2.4.2より、ターゲティングを行っている広告の場合にはデフォルトでインフォメーションアイコン(オプトアウトリンク)が表示されるようになります(ターゲティングを行っていない広告の場合は表示されません)。
インフォメーションアイコンはタップすることで、DSP事業者が指定したオプトアウトWebサイトページへ遷移します。
オプトアウトリンクはユーザーが広告のターゲティングをオプトアウト(拒否)することにより、ユーザーに関する情報の関連付けを防ぐことを可能とし、設置することで配信できるDSP事業者が増加します。

表示される場所は、setClickEvent(Context context, View view, ADGNativeAdOnClickListener listener)で指定したViewの右上に設置されます。
デフォルトの表示位置から変更する場合は、ADG.setInformationIconViewDefault(boolean b)を設定し、ADGInformationIconViewを生成してください。
ターゲティングを行っていない広告の場合は、ADGInformationIconViewを生成してもアイコンは表示されません。

インフォメーションアイコンの表示確認は、テストID48635を使用してください。

# 動画広告の実装について(Android: v2.9.0~(adg-2.9.0.aar))

ADGMediaViewを利用することで、動画広告を配置できます。

// メイン画像または動画が利用できるかどうかをチェックします。
if (nativeAd.canLoadMedia()) {
    // ADGMediaViewを生成します。
    ADGMediaView mediaView = new ADGMediaView(mActivity);

    // 必ずADGNativeAdの参照を追加してください。
    mediaView.setAdgNativeAd(nativeAd);

    // Viewを配置します。
    mMediaViewContainer.addView(mediaView,
        new LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT));

    // メイン画像または動画のロードを開始します。
    mediaView.load();

    // 不要になったタイミングでdestroyを呼び、破棄処理をおこなってください。
    // mediaView.destroy();
}

# ADGMediaView注意事項

  • 動画を再生するにはコンストラクタの引数にActivityを渡してください。
  • 動画と静止画が利用できる場合は、動画が優先されます。
  • 動画や静止画は配信案件によるため、必ずしも配信されるわけではありません。
  • android:hardwareAccelerated がfalseの場合はtrueにしてください。
  • とくに、複数の動画を配置する場合や、アプリ側でMediaPlayerを扱い、動画や音声を再生している場合、不要になったものから destroy を呼びだし、適宜破棄を行う必要があります。
    破棄されないままMediaPlayerの生成を繰り返すとクラッシュを引き起こす場合があります。

# テスト用ID

審査完了前に広告の掲載イメージをご確認頂く際は、以下のIDに置き換えご確認ください。
このIDをセットしたままアプリをリリースしないようご注意ください。

テストID 配信広告
48635 テスト広告

# 6. proguardの設定をする

Android SDK Getting Started / バナー広告からご確認ください。

Last Updated: 7/22/2024, 8:49:42 AM