
developer.android.com
인앱 업데이트 | Other Play guides | Android Developers
보안 패치 배포나 백엔드 API 호환성으로 인해 기존 앱 버전을 강제로 업그레이드해야 하는 일이 생겼다. 안드로이드 플레이스토어로 사용자를 무작정 이동시키기에는 사용자 불편함이 좀 있다. 앱 내부에서 할 수 있는 인앱 업데이트 API를 제공한다.
- 유연한 업데이트 : 백그라운드에서 다운로드를 진행해서 사용자가 앱을 그냥 쓸 수 있음. 기능 개선이나 권장 업데이트 정도에 사용한다.
- 즉시 업데이트 : 전체 화면 블로킹 UI를 띄워 업데이트가 끝나고 재시작할 때까지 앱 사용을 강제로 중단한다. 무조건 업데이트해야할 때 사용한다.

업데이트 가능 여부 확인
val appUpdateManager = AppUpdateManagerFactory.create(context)
val appUpdateInfoTask = appUpdateManager.appUpdateInfo
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
// Google Play Developer API에서 지정한 우선순위(0~5)에 따라 모드 분기
val priority = appUpdateInfo.updatePriority()
if (priority >= 4 && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// 강제 즉시 업데이트 실행
startUpdateFlow(appUpdateInfo, AppUpdateType.IMMEDIATE)
} else if (appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
// 유연한 백그라운드 업데이트 진행
startUpdateFlow(appUpdateInfo, AppUpdateType.FLEXIBLE)
}
}
}
앱 실행 시 AppUpdateManager를 통해 플레이스토어에 새로운 버전이 있는지 확인한다. Google Play Developer API를 사용해 트랙 배포 시 0부터 5까지 updatePriority를 부여할 수 있다. 우선순위 4 이상의 긴급 패치일 때는 IMMEDIATE, 일반 패치일 때는 FLEXIBLE로 분기하면 적절한듯. 이 부분은 제품마다 정의해서 쓰면 된다.
업데이트 플로우 진행 (Activity Result API)
private val updateActivityResultLauncher = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult()
) { result ->
if (result.resultCode != RESULT_OK) {
// 사용자가 즉시 업데이트를 취소하거나 거절했을 때의 예외 처리
Log.w("InAppUpdate", "업데이트가 취소되었거나 실패했습니다.")
}
}
private fun startUpdateFlow(appUpdateInfo: AppUpdateInfo, updateType: Int) {
val options = AppUpdateOptions.defaultOptions(updateType)
appUpdateManager.startIntentSenderUpdateFlow(
appUpdateInfo,
updateActivityResultLauncher,
options
)
}
appUpdateManager.startIntentSenderUpdateFlow 를 호출해서 구글 플레이 업데이트 대화상자를 트리거한다.
유연한 업데이트 모니터링 및 재시작 유도
FLEXIBLE 업데이트는 백그라운드에서 다운로드가 진행되므로 앱에서 InstallStateUpdatedListener를 통해 상태를 관찰해야 한다.
val listener = InstallStateUpdatedListener { state ->
if (state.installStatus() == InstallStatus.DOWNLOADED) {
// 다운로드가 완료되면 스낵바나 팝업으로 설치 안내
showUpdateCompleteSnackbar()
}
}
appUpdateManager.registerListener(listener)
다운로드가 완료되었을 때 다짜고짜 앱을 재시작해 버리면 쓰던 상태가 날라가버린다. 재시작 버튼을 제공하고 사용자가 직접 클릭했을 때 appUpdateManager.completeUpdate()를 호출해 앱을 재시작하는 편이 낫다. 다운로드 도중 앱이 백그라운드로 갔다 복귀했을 때 onResume에서 이미 DOWNLOADED 상태로 대기 중인지 체크해 주는 예외 처리도 해줘야 한다.