# Android SDK ネイティブ広告
# はじめに
開発環境としてAndroid Studioを利用し、インストール後の各種設定は準備されていることを前提にした手順となります。
# 対応バージョン
- Android 5.0以降(API Level 21)
# 導入の流れ
- SDKをダウンロードします
↓ - プロジェクトにSDKを追加します
↓ - AndroidManifest.xmlの設定を行います
↓ - Google Play Servicesの設定を行います
↓ - 例を参考に広告表示の実装を行います
↓ - 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 / バナー広告からご確認ください。