EEltaCrew
블로그

앱 17개에 강제 인앱 업데이트(IMMEDIATE)를 넣은 이유: 광고 SDK 교체 때 옛 버전 수익이 0 이었다

게시 2026-09-16실측 기준 2026-09-11읽는 시간 약 4분elta · EltaCrew

2026년 7월 광고 SDK 를 갈아탔을 때, 업데이트를 안 받은 사용자에게서는 수익이 0 이었습니다. 정책 수정도 광고 수정도 옛 버전에는 닿지 않습니다. Play In-App Update 를 IMMEDIATE 로 전 앱에 넣은 방법, 검증이 Play 설치본에서만 되는 이유, 그리고 함께 처리한 것들을 씁니다.

왜 강제인가

2026년 7월 중순, 운영 중인 전 앱에서 실제 광고 노출이 0 이 된 일이 있었습니다. 계정 문제도 무효 트래픽도 아니었고, 옛 광고 SDK(play-services-ads) 쪽이 깨진 것이었습니다. 차세대 SDK(ads-mobile-sdk)로 옮겨 전 앱을 다시 출시해 해결했는데, 그 뒤 몇 주 동안 보고서를 보니 업데이트를 받지 않은 사용자에게서는 여전히 수익이 0 이었습니다.

이 경험이 기준을 바꿨습니다. 광고 SDK 든 정책 대응이든 동의 폼이든, 고쳐서 올려도 옛 버전에 머무는 사용자에게는 닿지 않습니다. 선택적(FLEXIBLE) 업데이트는 사용자가 미루면 그만입니다. 그래서 2026년 9월 11일, 17개 앱 전부에 IMMEDIATE(강제) 인앱 업데이트를 넣고 일괄 출시했습니다. 새 버전이 Play 에 있으면 앱을 켤 때 구글의 전체화면 업데이트 화면이 뜨고, 업데이트 전에는 앱을 쓸 수 없습니다.

구현

의존성은 com.google.android.play:app-update:2.1.0 하나입니다. 앱마다 정적 메서드 하나짜리 클래스를 두고, 진입 액티비티의 onResume 에서 부릅니다.

핵심은 이것뿐입니다.

  1. AppUpdateManagerFactory.create(context).appUpdateInfo 로 업데이트 정보 요청
  2. updateAvailability() == UPDATE_AVAILABLE 이고 isUpdateTypeAllowed(IMMEDIATE) 이면
  3. startUpdateFlowForResult(info, activity, AppUpdateOptions.newBuilder(IMMEDIATE).build(), REQUEST_CODE)
  4. onResume 에서 DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS 면 다시 3번 (사용자가 중간에 나갔을 때 재개)

결과 콜백, 안내 문자열, 스낵바는 전부 없앴습니다. IMMEDIATE 는 구글 화면이 다 처리하기 때문에 앱 쪽 UI 가 필요 없습니다. 액티비티가 여러 개인 앱(리모컨 앱은 메인·블루투스·Wi-Fi 세 개)은 진입 가능한 액티비티 전부에서 부릅니다. 한 앱에만 있던 FLEXIBLE 구현은 IMMEDIATE 로 교체했습니다.

검증은 Play 설치본으로만

디버그 빌드나 사이드로드한 APK 에서는 getAppUpdateInfo 가 실패해 아무것도 뜨지 않습니다. 그래서 "넣었는데 안 뜬다"는 보고가 자주 나오는데, 대부분 확인 방법이 틀린 것입니다.

확인 순서는 이렇습니다.

  1. 낮은 versionCode 빌드를 내부 테스트 트랙에 올려 기기에 Play 로 설치
  2. 높은 versionCode 빌드를 같은 트랙에 올림
  3. 기기에서 앱을 켜면 강제 업데이트 화면이 떠야 함

실제로는 프로덕션에 출시된 뒤 실기기 Play 설치본에서 강제 업데이트 화면과 EEA 동의 폼이 뜨는 것까지 확인했습니다.

함께 처리한 것

같은 날 같은 출시에 두 가지를 더 실었습니다.

17개 앱을 하루에 빌드·서명·업로드하다 보니 사고도 있었습니다. 빌드를 여러 에이전트에 나눠 맡겼는데 9개가 서명 없이 나왔습니다. 서명 키 위치를 환경 변수로 넘기는 걸 지시에 안 적은 탓입니다. 업로드 전에 AAB 파일 안의 versionName 과 서명자를 소스와 대조하는 검사를 돌려서 잡았습니다. 파일 수정 시각으로는 구분이 안 됩니다. 한 앱은 옛 키스토어로 서명돼 Play 가 "wrong key" 로 거부했고, 공용 키스토어로 다시 서명했습니다.

버전 규칙

일괄 출시하면서 versionCode 규칙도 통일했습니다. versionCode 는 versionName 에서 점만 뺀 숫자입니다. 1.2.3 이면 123, 다음 릴리즈는 1.2.4 / 124. 릴리즈 한 번에 patch 하나. 앱 4개가 12, 13 같은 값을 쓰고 있어 맞췄습니다. 단, Play 는 versionCode 를 내릴 수 없기 때문에 이미 자릿수가 하나 많은 앱(예: 10018)은 낮추지 않고 그 자릿수를 유지하며 patch 만 올립니다.

정리

AndroidGoogle Play인앱 업데이트앱 운영

함께 읽기

R8 을 켜고 빌드는 통과했는데 앱이 깨졌다: 15개 앱에서 실제로 걸린 런타임 함정 5가지Play 의 2027년 코드 최적화 요건에 맞춰 앱 15개에 R8 을 켰습니다. 빌드는 전부 통과했지만 7개 중 2개가 실행 중에 깨졌습니다. Gson 역직렬화, getIdentifier 리소스 조회, Room _Impl, 디버그 빌드의 무효화 등 크래시 로그에 안 잡히는 유형을 정리합니다.판매자 계정 하나 켰다가 앱 21개 출시가 전부 막혔다: 한국 개인 개발자와 Play Console 「추가 정보 필요」후원용 인앱 상품을 테스트하려고 판매자 계정을 만든 직후, Play Console 이 사업자 등록 번호·통신판매업 신고번호를 요구하며 전 앱의 출시를 막았습니다. 상품을 지워도, 지급 계좌를 지워도 풀리지 않았고 지원팀의 최종 답은 "되돌릴 수 없다" 였습니다. 개인 개발자가 이 함정을 피하는 방법을 씁니다.데이터 보안 양식, 선언 0 인 앱이 적발되기 시작했다: 앱 21개 전수 감사와 CSV·API 로 고치는 법사용자가 손으로 입력한 남의 전화번호도 구글 기준 "전화번호 수집" 이었습니다. 거부를 한 번 받고 앱 21개의 데이터 보안 선언을 소스와 대조하니 11개가 어긋나 있었고, 그중 3개는 선언이 아예 0 이었습니다. 광고만 쓰는 앱도 선언 0 이면 안 되는 이유와, 5단계 마법사 대신 CSV 와 API 로 고치는 방법을 씁니다.