メインコンテンツまでスキップ

Android SDK Getting Started / ネイティブ広告

はじめに

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

対応バージョン

  • Android 6.0以降(API Level 23)

導入の流れ

  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()
メイン画像(長方形画像)URLADGNativeAd.getMainImage().getUrl()
メイン画像(長方形画像)幅ADGNativeAd.getMainImage().getWidth()
メイン画像(長方形画像)高さADGNativeAd.getMainImage().getHeight()
アイコン画像(正方形画像)URLADGNativeAd.getIconImage().getUrl()
アイコン画像(正方形画像)幅ADGNativeAd.getIconImage().getWidth()
アイコン画像(正方形画像)高さADGNativeAd.getIconImage().getHeight()
リード文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(nativeAdView)

adContainer.addView(nativeAdView, FrameLayout.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()
}
}
}
}

リトライの目安:

リトライの目安エラーコード
リトライ不要EXCEED_LIMIT / NEED_CONNECTION / NO_AD
リトライ可上記以外
補足

ADGクラスを利用している場合、ADG.stop() の実行時に ADGNativeAd.stop() も内部で実行されます。ADGNativeAd を直接管理する場合のみ ADGNativeAd.stop() を明示的に呼んでください。

注意: サンプル内の DownloadImageAsyncAsyncTask を使用していますが、API Level 30 で非推奨です。実運用では Kotlin Coroutines / Executors / 画像ライブラリ(Glide, Coil, Picasso など)の利用を推奨します。

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

  • 作成される広告イメージ

作成される広告イメージ

  • アプリに応じてカスタマイズください(画像ロード処理の非同期化など)。
  • レイアウトファイルは サンプル を参照してください。
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を生成してください。
getOptout() / getInformationIcon() / getAccompany() のいずれかが取得できない場合は、ADGInformationIconView を生成してもアイコンは表示されません。

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

インフォメーションアイコンの表示位置・スタイル

ADGInformationIconView は以下のオプションを指定できます。

オプション説明
CornerTOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT
BackgroundTypeWHITE, BLACK
expandable展開アニメーションの有効/無効
ADGInformationIconView(
context: Context,
nativeAd: ADGNativeAd,
expandable: Boolean,
corner: Corner,
backgroundType: BackgroundType
)
// 引数が少ないコンストラクタ
ADGInformationIconView(
context: Context,
nativeAd: ADGNativeAd
)

動画広告の実装について(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 / バナー広告からご確認ください。