개요
- 안드로이드 어플리케이션의 버전 관리를 위해 구글에서 In-App-Support를 사용하기 쉽도록 만든 라이브러리이다.
- 현재 안드로이드 어플리케이션 최신 버전 출시 후 강제 업데이트 하기 위해서는 플레이스토어에 올라간 버전을 가져와서, 앱 시작시 비교하여 하는 방법이였지만, In-App Update를 사용하면서 그럴 필요가 없어졌다.
- In-App Update를 적용하면 기존에는 플레이스토어에 가서 업데이트를 눌러야 했지만, 그럴 필요 없이 바로 업데이트를 할 수 있다.
Flexible OR Immediate
- Android In-App Update에서는 2가지 버전을 지원한다. 하나는 Flexible(권장 업데이트)이고, 다른 하나는 Immediate(필수 업데이트) 이다.
- Flexible(권장 업데이트)는 앱을 실행시키면 최신 버전 여부를 파악해 다이얼로그를 사용자에게 보여줍니다. 이건 사용자에게 선택할 기회를 주는 것으로 이전 버전을 쓸 수도 있고, 최신 버전을 업데이트 할 수도 있는 것이 큰 장점이다.
- Immediate(필수 업데이트)는 앱을 실행시키면 업데이트를 하라는 전체화면이 나온다. Immediate(필수 업데이트)는 이전 버전을 사용할 수 없도록, 최신 버전으로 무조건 업데이트를 유도할 수 있고, 업데이트가 완료되면 앱이 재실행된다.
사용방법
- In-App Update (인앱업데이트)는 안드로이드 5.0 (API 21) 이상부터 사용이 가능하며, Play Core Library 1.5.0이상을 안드로이드 스튜디오에 추가해야 합니다.
implementation 'com.google.android.play:core:1.7.3'
- 업데이트 가능 여부를 확인 하며, 가능하면 시작
private AppUpdateManager mAppUpdateManager;
private static final int RC_APP_UPDATE = 11;
- onStart() Method 안에서 아래 코드를 넣는다.
- 현재 예제는 Flexible (권장 업데이트)를 중심으로 작성하였으며, Immediate(필수 업데이트)를 적용하기 위해서는
AppUpdate.FLEXIBLE 대신 AppUpdateType.IMMEDIATE를 사용하면 된다.
mAppUpdateManager = AppUpdateManagerFactory.create(this);
mAppUpdateManager.registerListener(installStateUpdatedListener);
mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)){
try {
mAppUpdateManager.startUpdateFlowForResult(
appUpdateInfo, AppUpdateType.FLEXIBLE, MainActivity.this, RC_APP_UPDATE);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED){
//CHECK THIS if AppUpdateType.FLEXIBLE, otherwise you can skip
popupSnackbarForCompleteUpdate();
} else {
Log.e(TAG, "checkForAppUpdateAvailability: something else");
}
});
- 업데이트 상태를 체크
InstallStateUpdatedListener installStateUpdatedListener = new
InstallStateUpdatedListener() {
@Override
public void onStateUpdate(InstallState state) {
if (state.installStatus() == InstallStatus.DOWNLOADED){
//CHECK THIS if AppUpdateType.FLEXIBLE, otherwise you can skip
popupSnackbarForCompleteUpdate();
} else if (state.installStatus() == InstallStatus.INSTALLED){
if (mAppUpdateManager != null){
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
}
} else {
Log.i(TAG, "InstallStateUpdatedListener: state: " + state.installStatus());
}
}
};
- 업데이트 상태 콜백 받기
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_APP_UPDATE) {
if (resultCode != RESULT_OK) {
Log.e(TAG, "onActivityResult: app download failed");
}
}
}
- Flexible Update
private void popupSnackbarForCompleteUpdate() {
Snackbar snackbar =
Snackbar.make(
findViewById(R.id.coordinatorLayout_main),
"New app is ready!",
Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("Install", view -> {
if (mAppUpdateManager != null){
mAppUpdateManager.completeUpdate();
}
});
snackbar.setActionTextColor(getResources().getColor(R.color.install_color));
snackbar.show();
}
- Listener 해제를 잊으면 안된다. (onStop Method)에 추가
if (mAppUpdateManager != null) {
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
}
문제점 및 테스트 방법
- 문제점이라기보다는 In-App Update 특정상 테스트하기가 까다롭다는 것이다.
- 테스트 하기 위해서는 바로 업데이트하여 테스트하는 것보단 내부 테스트 트랙에 앱을 업데이트 하는 것이 낫다.
- FakeAppUpdateManager를 사용해서 테스트를 진행할 수 있다고는 하지만, 아직 사용해보지는 않았다.
- 내부 테스트 방법
1. In-App Update 적용한 AAB or APK를 내부테스트 트랙으로 출시
2. 테스트 폰에서 내부 테스트 트랙으로 올린 버전에 대한 앱 설치
3. buildVersion 올린 후 내부 테스트 트랙으로 다시 출시 (buildVersion이 이전버전보다 높아야합니다.)
4. 앱 실행 후 업데이트 되는지 확인.
- 내부 테스트 문제 (내부 테스트에도 올렸지만, 업데이트가 안되는 상황)
구글 문서에도 아래에 보면 이러한 내용이 나와 있다.
1. 테스트 하기전 구글 스토어에서 다운 받은 앱을 사용하세요.
2. 구글 스토어에 있는 어플리케이션 ID와 인증키가 동일해야 합니다.
3. 낮은 버전에서 높은 버전으로 테스트를 진행하세요.
4. 구글 플레이 캐시로 인해 업데이트가 안될 수 있습니다. 구글플레이 스토어를 완전히 종료 후 실행한 후 "나의 앱/게임 탭"에서 업데이트 가능 여부를 확인해 주세요.
+) 5. 앱 - 구글 플레이 스토어 - 저장공간 - 데이터 삭제 후 "나의 앱/게임 탭"에서 업데이트 가능 여부를 확인해 주세요.
후기
In-App Update를 적용하면서 이걸 들어본 개발자들은 안 쓸 이유가 없다고 생각한다. 별 다른 이유가 없다면 쓰는 것을 추천합니다 !!
출처
- https://developer.android.com/guide/playcore/in-app-updates?hl=ko#java (Google Developer 공식문서)
- https://black-jin0427.tistory.com/212
- https://stackoverflow.com/questions/55939853/how-to-work-with-androids-in-app-update-api