구글 AdMob(애드몹) 광고 연동하기 - 배너 광고

2024. 9. 24. 21:04[개발]/Kotlin 활용 앱 개발

# 애드몹 회원가입

https://admob.google.com/v2/home?authuser=0

 

AdMob

이메일 또는 휴대전화

accounts.google.com

 

# 앱 추가

https://admob.google.com/v2/apps/create?authuser=0

 

AdMob

이메일 또는 휴대전화

accounts.google.com

 

# 앱 기본 요건 확인

  • 최소 SDK 버전 21 이상
  • 33 이상 버전의 컴파일 SDK

컴파일 SDK 버전이 맞지 않으면 아래의 오류가 뜬다!

Failed to get service from broker. 
java.lang.SecurityException: Unknown calling package name 'com.google.android.gms'.
at android.os.Parcel.createExceptionOrNull(Parcel.java:3011)
at android.os.Parcel.createException(Parcel.java:2995)
at android.os.Parcel.readException(Parcel.java:2978)
at android.os.Parcel.readException(Parcel.java:2920)
at amok.a(:com.google.android.gms@243633032@24.36.33 (190800-675378931):36)
at ammr.z(:com.google.android.gms@243633032@24.36.33 (190800-675378931):143)
at altt.run(:com.google.android.gms@243633032@24.36.33 (190800-675378931):54)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at bqoh.ml(:com.google.android.gms@243633032@24.36.33 (190800-675378931):1)
at bqoh.dispatchMessage(:com.google.android.gms@243633032@24.36.33 (190800-675378931):5)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)

 

# 앱 설정

- settings.gradle.kts 파일에 아래 코드를 추가

pluginManagement {
  repositories {
    google()
    mavenCentral() // 추가
    gradlePluginPortal() // 추가
  }
}

dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  repositories {
    google() // 추가
    mavenCentral() // 추가
  }
}

 

- 앱 수준 gradle.kts 파일에 모바일 광고 SDK의 implementation 추가

dependencies {
  implementation("com.google.android.gms:play-services-ads:23.3.0") // 추가, 최신 버전 여부 확인
}

 

- AndroidManifest.xml 파일에 인터넷 사용 권한 허용(1), 앱 ID (2)를 아래와 같이 추가

<manifest>
	...
	<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
	...
  <application>
    <!-- Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 -->
    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID" // 추가
        android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/> // 추가
  </application>
</manifest>

 

- 서로 다른 라이브러리 내 중복된 속성 사용 블라블라..로 인한 오류가 뜰 경우 아래와 같이 코드를 수정

...
	<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
		...
        <property
            android:name="android.adservices.AD_SERVICES_CONFIG" // 추가
            tools:replace="android:resource" // 추가
            android:resource="@xml/gma_ad_services_config" /> // 추가
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>
		...
    </application>

</manifest>

*** 앱 ID에 들어가는 값은 출시 전까지 구글에서 제공하는 테스트 ID를 쓸 것 ****

앱 출시 전부터 발급받은 앱 ID로 실제 광고를 돌릴 경우 부당 광고수익 수취 시도로 판단되어 계정 정지 가능.

(테스트 ID: ca-app-pub-3940256099942544~3347511713)

(테스트 ID 링크 / 그냥 종합 안내에 쓰여있는 통합 테스트 ID 썼을 때 오류가 안 났음

- 종합 안내: https://developers.google.com/admob/android/quick-start?hl=ko#kotlin

 

시작하기  |  Android  |  Google for Developers

Android 앱을 제작 중인 Google AdMob 게시자를 위한 모바일 광고 SDK입니다.

developers.google.com

- 광고 유형별 테스트 ID: https://developers.google.com/admob/android/test-ads?hl=ko)

- 앱 출시할 때에는 애드몹 - 앱 정보로 가서 발급받은 앱 ID로 교체.

 

# 레이아웃에 광고 배너 추가

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".presentation.main.MainActivity"
    android:background="@color/background_color">

    <com.google.android.gms.ads.AdView
        android:id="@+id/adView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:adSize="BANNER"
        app:adUnitId="ca-app-pub-3940256099942544/9214589741"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/main_frame"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/adView"
        >

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

 

# MainActivity에서 광고 다는 코드 추가

class MainActivity : AppCompatActivity() {

    private lateinit var binding:ActivityMainBinding

	// 광고 사이즈 조절해주는 코드
    private val adSize: AdSize
        get() {
            val displayMetrics = resources.displayMetrics
            val adWidthPixels =
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    val windowMetrics: WindowMetrics = this.windowManager.currentWindowMetrics
                    windowMetrics.bounds.width()
                } else {
                    displayMetrics.widthPixels
                }
            val density = displayMetrics.density
            val adWidth = (adWidthPixels / density).toInt()
            return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, adWidth)
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val backgroundScope = CoroutineScope(Dispatchers.IO)
        backgroundScope.launch {
        // 광고 로드 전에 모바일 광고 SDK를 초기화(앱 실행 시 한 번 동작 필수)
        // Initialize the Google Mobile Ads SDK on a background thread.
            MobileAds.initialize(this@MainActivity) {}
        }

        setFragment(SignInFragment())

        setAd() // 광고 다는 메서드
    }

    private fun setFragment(frag : Fragment) {
        supportFragmentManager.commit {
            add(R.id.main_frame, frag)
        }
    }

    private fun setAd() {
        val adView = AdView(this)
        // 테스트 ID
        adView.adUnitId = "ca-app-pub-3940256099942544/9214589741"
        adView.setAdSize(adSize)

		// 광고 컨테이너를 새 adview로 교체
        binding.adView.removeAllViews()
        binding.adView.addView(adView)

		// 광고 빌더 생성 및 광고 로드
        val adRequest = AdRequest.Builder().build()
        adView.loadAd(adRequest)

    }
    override fun onPause() {
        super.onPause()
        binding.adView.pause() // 액티비티가 일시 정지되면 광고도 일시 정지
    }
    override fun onResume() {
        super.onResume()
        binding.adView.resume() // 액티비티가 다시 시작되면 광고도 다시 시작
    }
    override fun onDestroy() {
        super.onDestroy()
        binding.adView.destroy() // 액티비티가 파괴되면 광고 리소스 해제
    }
}