Android AdMob UMP(사용자 동의) 올바른 초기화 순서와 실패 Fallback 처리 방법
앱에 애드몹(AdMob) 광고를 붙일 때, 대뜸 배너 광고 코드부터 복사해서 넣으면 나중에 앱 시작 흐름이 꼬여서 고생하기 십상입니다. 특히 유럽 경제 지역(EEA)이나 미국 주 규정 등 개인정보 선택권이 강화된 지역을 고려하면, 광고 요청 전에 사용자 동의 상태를 확인하는 과정이 필수적입니다.
이래저래 앱을 운영하다 보니, Google UMP(User Messaging Platform) SDK를 활용한 동의 흐름을 광고 초기화 앞단에 제대로 배치하는 것이 광고를 띄우는 것보다 훨씬 중요하더군요. 자꾸 까먹어서 나중에도 바로 보고 적용할 수 있도록 실무 기준으로 깔끔하게 정리해 둡니다.
내가 겪은 문제와 자주 헷갈리는 지점들
보통 광고가 안 나오거나 정책 검수에서 반려되는 상황을 보면, 광고 SDK 자체의 문제라기보다는 "언제 광고를 요청할 것인가"에 대한 제어가 꼬여서 발생하는 경우가 대부분입니다.
성급한 광고 요청: 앱 시작 직후 동의 상태 업데이트가 끝나지도 않았는데 배너나 전면 광고를 로드함.
오류 처리 혼선: 동의 폼 표시 실패(네트워크 오류 등)를 광고 로딩 실패와 구분 없이 섞어서 처리함.
다시 열기 진입점 누락: 사용자가 마음이 바뀌어 개인정보 옵션을 재설정하고 싶을 때, 앱 내 설정 화면 등에서 동의 폼을 다시 열어줄 진입점을 제공하지 않음.
동의 업데이트 실패 시 대책 없음: 네트워크 단절 등으로 동의 정보 업데이트가 실패했을 때, 이전 세션의 상태를 체크하여 유연하게 넘어가는 기준이 없음.
민감 정보 노출: 블로그나 공개 GitHub 저장소에 예제 코드를 올리면서 실제 AdMob App ID나 테스트 기기 해시 ID를 그대로 노출함.
운영 관점에서는 광고 수익화보다 동의 흐름과 정책 대응을 완벽히 다져놓는 것이 먼저입니다. 이 흐름이 불안정하면 사용자 신뢰는 물론 정책 위반 경고를 받기 딱 좋습니다.
기본 개념: UMP는 광고 SDK 앞단의 '방어벽'이다
UMP SDK는 광고를 보여주는 도구가 아니라, 광고를 보여주기 전 사용자의 개인정보 선택권을 수집하고 관리하는 SDK로 이해하셔야 안전합니다. 즉, 애드몹 광고 요청은 UMP 동의 상태 확인이 완료된 이후에 진행되어야 합니다.
| 구성 요소 | 역할 | 주의할 점 |
| AdMob App ID | 앱을 AdMob 플랫폼에 연결하는 고유 ID | 공개 글이나 오픈소스 공유 시 절대 실제 값을 노출하면 안 됨 |
| UMP SDK | 사용자 개인정보 선택 관리 및 추적 | 앱이 시작될 때마다 최신 동의 정보를 업데이트해야 함 |
| 동의 폼 (Consent Form) | 요건에 따라 사용자에게 표시되는 동의 유도 UI | AdMob 콘솔의 'Privacy & messaging' 설정과 연동됨 |
| canRequestAds() | 광고 요청 가능 여부 확인 반환값 | 이 값이 true일 때만 비로소 광고 로딩 및 초기화를 시작함 |
| 광고 단위 ID | 배너, 전면, 보상형 등 실제 광고가 붙는 영역 ID | 코드 예제나 테스트 단계에서는 반드시 더미/테스트 ID 사용 |
권장하는 앱 시작 초기화 순서
저의 경우 앱 시작(Splash 화면 등) 시점에 아래 순서대로 처리되도록 구조를 잡고 있습니다.
AdMob 콘솔 설정: 먼저 AdMob 콘솔 내 Privacy & messaging 메뉴에서 메시지를 생성해 둡니다.
의존성 추가: 앱 프로젝트에 UMP SDK 라이브러리를 추가합니다.
AndroidManifest 설정:
AndroidManifest.xml에 AdMob Application ID를 빠뜨리지 않고 등록합니다.동의 정보 업데이트: 앱 시작 시
requestConsentInfoUpdate()를 호출하여 최신 동의 상태를 서버로부터 가져옵니다.동의 폼 표시 여부 결정: 필요한 경우(유럽 지역 유저 등)
loadAndShowConsentFormIfRequired()를 통해 동의 UI를 화면에 띄웁니다.조건부 광고 초기화:
canRequestAds()가 true인 것을 확인한 뒤에만 광고 SDK 초기화 및 실제 광고 로드(loadAd)를 진행합니다.재진입점 제공: 설정 화면 등에 개인정보 옵션을 다시 열 수 있는 버튼과 연결합니다.
핵심은 "광고 요청 전 동의 상태 확인"입니다. 동의 상태 확인과 광고 로드가 비동기 흐름 속에서 중복 실행되지 않도록 안전장치(플래그 변수)를 두는 것도 중요합니다.
실무 적용 핵심 예제 코드 (Kotlin)
실제 프로젝트에 바로 적용할 수 있도록 정리한 AdConsentManager 클래스 예시입니다. Google 공식 문서 방향성을 따르되, 중복 호출을 방지하는 플래그를 포함했습니다.
class AdConsentManager(
private val activity: Activity,
private val onReadyToRequestAds: () -> Unit,
) {
private val consentInformation: ConsentInformation =
UserMessagingPlatform.getConsentInformation(activity)
// 광고 SDK 초기화가 여러 번 실행되는 것을 막기 위한 플래그
private var isMobileAdsStartCalled = false
fun gatherConsent() {
val params = ConsentRequestParameters.Builder()
.build()
// 1. 최신 동의 정보 업데이트 요청
consentInformation.requestConsentInfoUpdate(
activity,
params,
{
// 업데이트 성공 시: 필요한 경우 동의 폼을 로드하고 표시함
UserMessagingPlatform.loadAndShowConsentFormIfRequired(activity) { formError ->
if (formError != null) {
// 운영 앱에서는 보안을 위해 민감 정보 없이 에러 코드 위주로 로그만 남김
}
// 동의 폼 처리가 끝난 후, 광고 요청이 가능한 상태인지 최종 확인
if (consentInformation.canRequestAds()) {
initializeAdsOnce()
}
}
},
{ requestError ->
// 업데이트 실패 시 (ex. 네트워크 오프라인):
// 무조건 막기보다 이전 세션에 저장된 정보를 기준으로 권한을 확인하여 유연하게 대처
if (consentInformation.canRequestAds()) {
initializeAdsOnce()
}
},
)
// 호출 시점에 이미 조건이 충족되어 있다면 즉시 실행 시도
if (consentInformation.canRequestAds()) {
initializeAdsOnce()
}
}
private fun initializeAdsOnce() {
if (isMobileAdsStartCalled) return
isMobileAdsStartCalled = true
// 최종적으로 AdMob SDK를 초기화하고 콜백을 통해 광고 로드를 시작함
MobileAds.initialize(activity) {
onReadyToRequestAds()
}
}
// 설정 화면 등에서 개인정보 재설정 버튼을 보여줘야 하는지 여부 판단
fun isPrivacyOptionsRequired(): Boolean {
return consentInformation.privacyOptionsRequirementStatus ==
ConsentInformation.PrivacyOptionsRequirementStatus.REQUIRED
}
// 사용자가 설정 화면에서 동의 상태를 다시 변경하고자 할 때 호출
fun showPrivacyOptions() {
UserMessagingPlatform.showPrivacyOptionsForm(activity) { formError ->
// 동의 변경 완료 또는 취소 후 필요한 후처리 로직 위치
}
}
}
주의하셔야 합니다
canRequestAds()의 검증 지점은 동의 업데이트 성공 콜백, 실패 콜백, 그리고 함수 진입 시점 등 여러 곳이 될 수 있습니다. 따라서isMobileAdsStartCalled같은 플래그를 두어MobileAds.initialize가 중복으로 호출되는 현상을 확실하게 막아주어야 안전합니다.
상황별 실패 Fallback 처리 가이드
동의 정보 업데이트나 폼 표시 과정에서 에러가 났다고 해서 무조건 앱 사용을 막아버리면 유저들이 다 이탈합니다. 실패는 분리해서 기록하되, 자연스럽게 다음 흐름으로 넘어가도록 설계해야 합니다.
| 유저 상황 | 추천하는 Fallback 처리 방식 |
| 동의 업데이트 성공 + 폼 노출 필요 없음 | 바로 canRequestAds() 확인하고 광고 로드 단계로 진입 |
| 동의 업데이트 성공 + 폼 노출 완료 | 사용자가 선택을 마치면 canRequestAds() 확인 후 광고 로드 |
| 동의 폼 표시 실패 (UI 에러 등) | 에러 로그만 남기고, 혹시 기존 동의로 canRequestAds()가 유효한지 확인 후 진행 |
| 동의 정보 업데이트 실패 (네트워크 단절 등) | 대뜸 앱을 막지 말고, 이전 세션 상태 기준으로 canRequestAds()를 체크하여 처리 |
canRequestAds() 결과가 false인 경우 | 광고 요청을 완전히 보류하되, 콘텐츠 화면은 정상적으로 제공 |
보안 및 실무 운영 체크리스트
[ ] 실제 운영 환경의 AdMob App ID와 광고 단위 ID를 코드나 공개 레포지토리에 커밋하지 않았는가?
[ ] 개발 중 사용한 테스트 디바이스의 해시 ID를 제거하거나 환경 변수로 분리했는가?
[ ] 광고를 로드하기 전, 최상단 앱 시작 루틴에서 동의 정보 업데이트 흐름을 태우는가?
[ ] 다른 무엇보다
canRequestAds()가true일 때만 광고 요청 로직이 실행되도록 가뒀는가?[ ] 비동기 콜백 중복 실행으로 인해 광고 초기화가 여러 번 실행되지 않도록 방어 플래그를 심었는가?
[ ] 설정(Setting) 메뉴에 개인정보 동의를 언제든 재수정할 수 있는 진입점 버튼을 마련했는가?
요약 및 추천 대상
이 구조가 꼭 필요한 앱:
AdMob 배너, 전면, 보상형 광고를 하나라도 사용하는 Android 앱
국내뿐만 아니라 해외(특히 유럽, 미국) 글로벌 유저에게도 배포할 계획이 있는 앱
앱 내 설정 화면에서 유저에게 개인정보 선택권을 명확히 보장해 주려는 앱
우선순위 재검토가 필요한 앱:
아동 유저가 메인 타깃인 미성년자 대상 앱 (정책 검토가 별도로 필요합니다)
의료, 금융 등 민감 카테고리를 다루는 콘텐츠 앱
AdMob 외에 타 광고 네트워크를 미디에이션(Mediation)으로 엮어 자체 CMP를 쓰는 앱
짧은 마무리
AdMob 광고 적용은 얼핏 가이드 문서의 코드 몇 줄 복사해 넣으면 금방 끝날 것 같지만, 실제로 안정적으로 운영해 보면 동의 흐름, 예외 처리, 그리고 규정 준수 처리가 작업의 90%를 차지합니다.
초반에 뼈대를 잘못 잡으면 나중에 광고가 왜 안 나오는지 원인 추적하기도 굉장히 힘들어집니다. 처음부터 "동의 정보 업데이트 -> 폼 확인 -> canRequestAds() 검증 후 광고 로드"라는 방어적인 초기화 흐름을 제대로 설계해 두고 구현을 시작하시기 바랍니다.
댓글
댓글 쓰기