이전 글에서 안드로이드 앱 업데이트에 필요한 버전 정보와 인앱 업데이트 기능에 대해 알아보았다. 이번 글에서는 인앱 업데이트 중 즉시 업데이트에 대해서 알아보자.
즉시 업데이트에 대한 기본적인 설명은 지난 글에서 설명했으니, 구현 방법과 실제 코드를 살펴보자 !
공식문서를 보면 구현 방법이 굉장히 자세히 나와있으니 자세한 과정은 공식문서를 참고하고, 여기서는 내가 구현한 방법만 설명하겠음
module 수준의 build.gradle
파일에 아래와 같이 의존성을 추가해준다.
내가 만들었던 앱은, 앱을 시작하면 우선 스플래쉬 화면이 띄워지고, 그 이후로 회원가입 및 자동로그인 여부에 따라서, 다음 플로우로 앱이 진행된다. 따라서, 우선 앱의 진입점인
SplashActivity
에서 스플래쉬 화면을 띄워주고,
그 이후에 업데이트된 새로운 버전이 플레이 스토어에 있는지 확인해
- 새로운 버전이 있고 이것이 중요한 업데이트(즉시 업데이트)라면 즉시 업데이트 다이얼로그가 띄워지고
- 새로운 버전이 없거나, 새로운 버전이 있지만 이것이 중요한 업데이트가 아니라면 다음 플로우로 앱을 진행하도록 구현하였다.
private fun checkAppUpdate() {
appUpdateManager = AppUpdateManagerFactory.create(this)
val appUpdateInfoTask = appUpdateManager.appUpdateInfo
...
}
AppUpdateManager
객체를 초기화하고 AppUpdateInfo
인스턴스를 appUpdateInfoTask
변수에 할당한다. AppUpdateInfo
인스턴스에 업데이트 사용 가능 상태가 포함되어 있다.// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
) { // 업데이트가 있는 경우
// 즉시 업데이트 실행
}
else { // 업데이트가 없는 경우
// 아무 실행도 하지 않고, 다음 플로우로 앱 진행
setNextActivity()
}
if
=> if 문의 조건식은 사용가능한 업데이트가 있고, 그 업데이트가 즉시 업데이트에 해당하는 업데이트인 경우라면 true를 반환하고, 즉시 업데이트를 호출하는 로직을 구현해주면 된다.else
=> 사용가능한 업데이트가 없거나 있는데 이것이 유연한 업데이트라면, 앱의 스플래쉬 화면 다음 플로우로 진행시켜주는 setNextActivity()
를 호출하도록 해준다. onActivityResult()
와 onResume()
을 override 해줌으로써, 업데이트가 취소되거나 중단되었을 때도, 다시 즉시 업데이트를 실행하고, 다시 재개하도록 해주었다. => 사실 이 부분은, 정확히 확신이 없어 다른 블로그 및 코드를 참고하는 것을 추천드린다.🙇🏻♂️
❓ 즉시 업데이트와 유연한 업데이트가 있는 건 알겠고, 이에 따라 다른 플로우로 업데이트가 진행되는 건 알겠는데, 이를 어떻게 구분하지 ??
❓ 내가 플레이스토어에 새로운 버전의 앱을 업로드하면, 이 업데이트가 즉시 업데이트인지 유연한 업데이트인지 사용자의 기기에 설치되어있는 앱에서 어떻게 구분하지 ??
공식문서를 보면 이렇게 appUpdateInfo.isUpdateTypeAllowed()
메서드의 인자에 AppUpdateType.IMMEDIATE
또는 AppUpdateType.FLEXIBLE
값을 넘겨주어 이를 통해 구분하는 것처럼 나와있었다.
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
) { // 업데이트가 있는 경우
Timber.e("인앱업데이트 있음")
// 즉시 업데이트 실행
... }
else if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)
)
그래서 처음에는 이렇게 if
문을 분기처리해서 구현하려고 했다.
하지만 여러번의 구글링 결과,,,,
현재 플레이스토어에 업로드된 앱의 버전이 이전 앱 버전보다 높아 업데이트가 가능한 상태이면,
appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
와
appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)
모두 true를 반환한다고 한다 !!그리고 심지어 플레이스토어에 앱 파일을 올릴 때, 즉시 업데이트인지 유연한 업데이트인지를 개발자가 설정할 수 있는 방법이 없다고 한다 !
그래서 위처럼 if
문 분기처리로 구현해도 즉시 업데이트와 유연한 업데이트를 구분할 수 없다는 것이다 ㅠㅠ. 내가 원하는 건 중요한 업데이트이면 즉시 업데이트, 중요하지 않은 업데이트면 유저가 선택적으로 업데이트하도록 하는 것인데, 위의 if
문처럼 구현하면 어떤 업데이트더라도 무조건 즉시 업데이트가 실행되도록 될 것이다.
여기를 보면 나와 같은 고민을 하는 사람들의 절규를 볼 수 있다 ㅋㅋㅋ 구글은 이에 대한 조치를 빨리 취해야 한다!! 고 주장하는 사람들 ㅋㅋ 일해라 구글
그래서 어쨌든 ! 내가 원하는 분기처리를 하기 위해서 새로운 방법들을 찾아보았고, 시도할만한 방법들이 꽤 있었고, 이중에서 한가지 방법을 선택해 구현했다.
appUpdateInfo.availableVersionCode()
이용개발자가 조작할 수 있는 버전 정보에 대한 data는 versionCode
, versionName
이 두 가지 뿐이고, 실제로 업데이트 로직에 사용되는 data는 versionCode
이므로
내가 만약 새로운 버전의 앱의
versionCode
에 접근할 수만 있다면, 이전 버전의versionCode
와 새로운 버전의versionCode
값의 차이를 이용해 중요한 업데이트, 덜 중요한 업데이트를 구분할 수 있지 않을까 ?나 좀 천재인듯
라는 생각이 들었다. 그리고, 만약 중요한 업데이트면 versionCode를 이전 versionCode에 비해 5이상 증가시키고 덜 중요한 업데이트면 5미만으로 증가시킨다는 규칙을 정해놓는다면, 앱을 실행시킬 때마다 기존 설치되어있는 앱의 버전의 versionCode
와 (업데이트가 있을 시)앱 스토어의 새로운 버전의 versionCode
를 비교해 5이상 차이가 나면, 즉시 업데이트를 실행시키는 것이다 !!
그래서 이에 대해 구글링해보니 앱스토어의 새로운 버전에 대한 versionCode
에 접근하는 메서드가 있었고, 이를 이용해 구현하였다.
이전 글에서 작성했듯이 versionCode
data는 module 수준의 build.gradle
파일에서 확인및 변경이 가능하다. 그래서, 앱 출시를 위해 번들 파일을 추출할 때 build.gradle
파일에서 이 값을 설정하면 되고, 이에 대해서 접근하기 위해서는 BuildConfig.VERSION_CODE
를 통해서 접근하면 된다.
그리고 플레이스토어의 새로운 버전에 대한 versionCode
는 appUpdateInfo.availableVersionCode()
메서드를 이용해 접근하면 된다.
그리고 이 두 버전코드의 값의 차이를 이용해 이 값이 5 이상이면, 강제 업데이트를 실행하기 위해 appUpdateManager.startUpdateFlowResult()
메서드를 실행해주었다.
5 이상이 아니라면, 중요한 업데이트가 아니므로, 다음 플로우로 앱을 진행시켜 주기위해 setNextActivity()
메서드를 실행시켜 주었다.
이 방법 외에도, 여러 사람들이 다양한 방법을 시도해, 내가 직면한 문제를 해결하고 있었다. 그 중 "오, 괜찮은데?" 라는 생각이 들었던 방법이 있었지만, 위의 방법이 최선이라고 판단해서 시도해보진 않았다.
공식문서 업데이트 우선순위 방법
이는 공식문서에 나와있는 내용이지만, 구글링을 해본 결과 현재로서는 굉장히 사용하기 어려운 내용이라고 나와있었다.... 심지어 어떤 개발자가 "이 Google Play Developer API를 사용하기 위해 공부하는 시간이 앱 전체를 만드는 시간보다 더 들겠다" 라고 글을 써놓은 것을 봤다,, 그래서 그냥 빠르게 pass 했다.
Firebase remoteconfig 이용
Firebase를 이용해 구분하는 방법도 있는 것 같았다. 앱을 업데이트 할 때마다 firebase remoteconfig에 즉시 업데이트인지 아닌지를 구분할 수 있도록 data를 설정하고, 앱을 실행할 때마다 firebase에서 이 값을 불러와서 업데이트 분기처리를 해주도록 하는 방식인 것 같았다. 하지만 나는 Firebase에 대해서 잘 몰라서 이것도 Pass 했다. Firebase를 잘 아시는 분들은 이를 이용하면 굉장히 괜찮은 방법이라고 생각된다 ! 나도 firebase 공부해봐야겠다👀
Firebase remoteconfig 관련 내용이 있는 링크를 남겨둔다.
이제 코드 구현을 완료했으므로 실제로 작동하는지를 테스트해봐야 한다.
등 여러가지 테스트 방법이 있었지만, 플레이스토어에 한번 출시를 해야 그 다음 테스트가 잘 된다는 소리도 있었고, 나도 저 방법들을 써봤지만, 뭔가 잘 되지는 않았기 때문에 그냥 정식 출시를 통해 테스트 하는 방법이 제일 좋은 방법인 것 같다!
안드로이드 앱 번들 파일 추출 시 서명 관련 내용