InAppUpdate
인 앱 업데이트 기능은 앱 내에서 사용자의 업데이트를 유도하는 기능으로 2019년 Google IO에서 처음 소개되었습니다!
안드로이드 5.0(Api level 21) 이상부터 사용 가능하고 Play Core Library 버전도 1.5.0 이상을 사용해야 합니다.
의존성 추가
implement 'com.google.android.play:app-update-ktx:2.1.0'
업데이트 가능 여부
private val appUpdateManager: AppUpdateManager by lazy {
AppUpdateManagerFactory.create(context)
}
val appUpdateInfoTask = appUpdateManager.appUpdateInfo
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
// 인 앱 업데이트 코드 실행
} else {
// 업데이트 가능하지 않음
}
}
인 앱 업데이트 가능 여부는 AppUpdateManager의 AppUpdateInfo 객체를 통해 알 수 있습니다. AppUpdateInfo 객체를 Task 객체로 비동기로 데이터를 받아오기 때문에 콜백 함수를 등록해야 하는데요. ktx 라이브러리를 사용 중이라면 await으로 코루틴을 사용하여 동기적으로 바로 받아올 수도 있습니다 :)
업데이트 성공 여부
appUpdateLauncher = registry.register(
InAppUpdateEvent::class.java.simpleName,
owner,
ActivityResultContracts.StartIntentSenderForResult()
) { result ->
when (result.resultCode) {
Activity.RESULT_OK -> {
onAppUpdateCompleted()
}
Activity.RESULT_CANCEL -> {
//업데이트 실패
}
}
}
인 앱 업데이트 최종 성공 여부는 ActivityResultLauncher 객체를 통해 받아올 수 있어요 :)
동작 방식
인 앱 업데이트는 2가지 방식으로 업데이트 기능을 유도합니다.
유연한 업데이트
업데이트를 하려면 aab 또는 apk를 설치하는 시간이 필요한데요. 유연한 업데이트는 설치 파일을 다운로드를 백그라운드로 진행하면서 그동안 사용자는 자유롭게 앱 사용을 하길 원할 때 사용합니다. 다운로드가 완료되면 업데이트 팝업으로 이동하는 프로세스로 진행됩니다.
따라서 유연한 업데이트는 업데이트의 중요성이 크지 않거나 앱 조작이 미숙한 사용자들이 많은 앱에서 고려되면 좋습니다.
유연한 업데이트 실행
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
appUpdateLauncher,
AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE).build()
)
유연한 업데이트는 AppUpdateOptions.Builder에서 AppUpdateType.FLEXIBLE을 넘겨서 실행할 수 있어요.
설치파일 다운로드 성공 & 실패 처리
백그라운드에서 다운로드를 진행하면서 네트워크 상태 혹은 Google Play 앱 상태에 따라서 여러 케이스가 발생할 수 있을 텐데요. 인 앱 업데이트는 다음과 같이 3가지 상태로 정의되고 있습니다.
- 설치 파일 다운로드 중
- 설치 파일 다운로드 성공
- 다운로드 실패
그래서 유연한 업데이트 경우에는 해당 상태에 대한 적절한 처리를 개발자가 해줘야 합니다.
val listener = InstallStateUpdatedListener { state ->
when (state.installStatus()) {
InstallStatus.DOWNLOADING -> {
showProgressBar()
}
InstallStatus.DOWNLOADED -> {
showConfirm() {
//업데이트 시작
appUpdateManager.completeUpdate()
}
}
InstallStatus.FAILED -> {
showErrorSnackBar()
}
}
}
설치 파일 다운로드가 완료되면 completeUpdate 함수를 호출해서 업데이트를 시작할 수 있는데요. 이때 앱이 포그라운드일 때랑 백그라운드 일 때랑 동작이 다르데요.
포그라운드에서 업데이트를 시작할 때는 예시 사진처럼 전면으로 업데이트 진행되는 화면이 표시되고 업데이트가 완료되면 기본 활동으로 앱이 재시작합니다. 백그라운드에서 업데이트를 시작할 때는 백그라운드에서 그대로 설치가 된다고 하네요. 참고하시면 좋을 것 같아요.
즉시 업데이트
즉시 업데이트는 앱 설치하는 화면으로 즉시 전환되면서 업데이트를 진행합니다. 이는 사용자의 앱 사용을 강제적으로 막는 방법이기 때문에 업데이트가 중요한 경우 고려하면 좋습니다.
그리고 유연한 업데이트와 달리 설치 파일의 다운로드가 해당 화면에서 쭉 진행되는데요. 따라서 다운로드 실패, 성공에 대한 처리를 개발자가 따로 처리해주지 않아도 됩니다.
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
appUpdateLauncher,
AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build()
)
즉시 업데이트는 AppUpdateOptions.Builder에서 AppUpdateType.IMMEDIATE을 넘겨서 실행할 수 있어요.
우선순위 설정
문구 수정처럼 간단한 업데이트의 경우 인앱 업데이트를 비활성화하고 싶을 수 있습니다.
Google Play에 배포된 앱 버전에 우선순위를 부여하는 기능을 사용해서 0부터 5까지의 숫자를 부여합니다.
5는 가장 높은 우선순위를 의미하는데요. 이러한 우선순위 값에 따라서 업데이트 유도 동작을 컨트롤할 수 있습니다.
val appUpdateManager = AppUpdateManagerFactory.create(context)
val appUpdateInfoTask = appUpdateManager.appUpdateInfo
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.updatePriority() >= 4 //우선순위 체크
...)) {
}
}
한가지 아쉬운 점으로 우선순위를 설정하는 방법은 Google Developer API를 통해서만 가능합니다.
오류 수정
implement ("androidx.navigation:navigation-dynamic-features-fragment:$nav_version") {
exclude(group : "com.google.android.play", module : "core")
}
play core 라이브러리 버전을 올려도 반영이 안 되는 이슈가 있었는데요. navigation 관련 라이브러리에서 Play Core가 포함되어 있던 문제가 있었습니다. 그래서 위처럼 navigation 라이브러리에서 play core 의존성을 제거해 주면 좋을 것 같아요
https://issuetracker.google.com/issues/237574816
주의사항
인 앱 업데이트는 Google Play에서 업데이트를 받아와야 해서 만약 Google 계정 로그인이 안된 기기라면 업데이트 정보를 불러올 수 없습니다.
참고
'Android > Common' 카테고리의 다른 글
[Android] Notification MessageStyle에 이미지 표시하기 (2) | 2025.01.01 |
---|---|
[Android] touchDelegate로 뷰 계층 제약 없이 터치 영역 확장하기 (1) | 2023.11.30 |
[Android] 앱 성능 개선 - 앱 시작 시간 (1) | 2023.10.10 |
[Android] minSdk, compileSdk, targetSdk (0) | 2023.09.25 |
[Android] Radius 올바르게 적용하기 (0) | 2023.05.24 |