🔥

JetpackCompose AdMobバナー広告使用例

2023/10/11に公開

AdMobとは

ざっくり言うとモバイルアプリの収益化で利用するGoogleのアプリ内広告配信サービスです

https://developers.google.com/admob?hl=ja

使用方法

公式のSDKではまだCompose化に対応していないので

一番楽に導入する方法としてバナー広告をCompose化して

それを表示したい箇所で使用するという感じです。

https://developers.google.com/admob/android/banner?hl=ja

サンプルコード

@Composable
fun AdWidget(
    adType: AdType,
    contentsType: AdCustomTargetingContentsType,
    positionType: AdCustomTargetingPositionType,
    isLoggedIn: Boolean,
    contentsId: String? = null,
    tagId: String? = null,
    serialNumber: String? = null,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center
) {
    val loadingModifier: Modifier = when (adType) {
        AdType.Banner -> Modifier
            .height(50.dp)
            .width(320.dp)

        AdType.LargeBanner -> Modifier
            .height(100.dp)
            .width(320.dp)

        AdType.MediumRectangle -> Modifier
            .height(250.dp)
            .width(300.dp)
    }.background(AppTheme.colors().PrimaryGray)

    var isError by remember { mutableStateOf(false) }

    Box(modifier = modifier, contentAlignment = alignment) {
        Box(
            modifier = loadingModifier, contentAlignment = Alignment.Center
        ) {
            if (isError) {
                Column(
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(
                        text = stringResource(id = R.string.ad_error_title),
                        style = AppTheme.typography().JP_Bold_M_14px,
                        color = AppTheme.colors().DarkGray
                    )
                }
            }
        }
        AndroidView(modifier = Modifier.fillMaxWidth(), factory = { context ->
            AdManagerAdView(context).apply {
                setAdSizes(
                    if (adType == AdType.MediumRectangle) AdSize.MEDIUM_RECTANGLE
                    else AdSize.BANNER, AdSize.LARGE_BANNER
                )
                adUnitId =
                    if (adType == AdType.MediumRectangle) AdCustomTargetingUnitIdType.RECTANGLE.unitId
                    else AdCustomTargetingUnitIdType.OVERLAY.unitId
            }
        }, update = {
            it.apply {
                adListener = object : AdListener() {
                    override fun onAdFailedToLoad(error: LoadAdError) {
                        isError = when (error.code) {
                            0, 1, 2, 3 -> true
                            else -> false
                        }
                    }
                }
                loadAd(AdManagerAdRequest.Builder().apply {
                    BaseAdCustomTargetingType.values().forEach { baseAdCustomTargetingType ->
                        when (baseAdCustomTargetingType) {
                            BaseAdCustomTargetingType.Env -> addCustomTargeting(
                                baseAdCustomTargetingType.key,
                                if (BuildConfig.FLAVOR == "prod") AdCustomTargetingEnvType.REAL.name else AdCustomTargetingEnvType.TEST.name
                            )

                            BaseAdCustomTargetingType.VersionId -> addCustomTargeting(
                                baseAdCustomTargetingType.key, baseAdCustomTargetingType.value ?: ""
                            )

                            BaseAdCustomTargetingType.ScreenType -> addCustomTargeting(
                                baseAdCustomTargetingType.key, baseAdCustomTargetingType.value ?: ""
                            )

                            BaseAdCustomTargetingType.Contents -> addCustomTargeting(
                                baseAdCustomTargetingType.key, contentsType.name
                            )

                            BaseAdCustomTargetingType.UserType -> addCustomTargeting(
                                baseAdCustomTargetingType.key,
                                if (isLoggedIn) AdCustomTargetingUserType.MEMBER.name else AdCustomTargetingUserType.GUEST.name
                            )

                            BaseAdCustomTargetingType.Position -> addCustomTargeting(
                                baseAdCustomTargetingType.key, positionType.name
                            )

                            BaseAdCustomTargetingType.ContentsId -> if (!contentsId.isNullOrBlank()) {
                                addCustomTargeting(
                                    baseAdCustomTargetingType.key, contentsId
                                )
                            }

                            BaseAdCustomTargetingType.TagId -> if (!tagId.isNullOrBlank()) {
                                addCustomTargeting(
                                    baseAdCustomTargetingType.key, tagId
                                )
                            }

                            BaseAdCustomTargetingType.Num -> if (adType != AdType.Banner && !serialNumber.isNullOrBlank()) {
                                addCustomTargeting(
                                    baseAdCustomTargetingType.key, serialNumber
                                )
                            }
                        }
                    }
                }.build())
            }
        })
    }
}

解説

  • adTypeでバナー広告の種類を簡単に変えることができるように定義
  • isErrorとonAdFailedToLoadで読み込みに失敗した時はエラー表示
  • loadAd配下はカスタム広告表示する際にカスタムkeyなどを簡単に渡せるようにしたもの
    • ここはそれぞれのプロジェクトに合った形でいい感じにしてください

AdMobのエラーについて

公式ドキュメントでは触れられていなかったので軽くメモ代わりに記載

{
  "Code": 3,
  "Message": "No ad config.",
  "Domain": "com.google.android.gms.ads",
  "Cause": "null",
  "Response Info": {
    "Response ID": "null",
    "Mediation Adapter Class Name": "",
    "Adapter Responses": [],
    "Response Extras": {}
  }
}

なんかこんな感じに返ってくるのでエラーハンドリングしたい場合は

この辺の値使って良しなにすればできるはずです。


ネイティブ広告について

Composeでもできるかもしれませんが

自分は調査時間が足りず実装まですることができなかったので

深くは試すことができませんでした。

できた人いたら教えてください;;;


こちらの方が実装例をあげていました!!

https://shinagawa.app/posts/admob_native_ad_android/

参考記事

https://github.com/googleads/googleads-mobile-android-examples/releases/tag/5.8

https://qiita.com/tsumuchan/items/3e88e8fcc78a2781df8

https://stackoverflow.com/questions/72424892/is-is-possible-to-use-native-ads-with-jetpack-compose

Discussion