こんにちは、ZAICO開発チームの宮下です。
Androidアプリを開発していると全てのユーザーに早く新しいバージョンにアップデートしてほしい場面がよく出てきます。そんな「早く新しいバージョンにアップデートしてくれ〜」という状況を改善する方法が今回紹介するアプリ内アップデートです。
実行中のアプリよりGoogle Playに新しいバージョンのアプリが存在する時に、アプリ実行中にアプリの更新を促す画面が表示される仕組みです。
下記が完成イメージで、弊社のZAICOアプリを起動するとすぐに自動更新画面が表示され、更新を押すとアプリの更新が始まる、という感じです。
なお、今回の方法(GoogleのGoogle Play Core Libraryを使う)ではいわゆる強制アップデート、アップデートをしないとアプリが使えない、という状況は作れません。上記のデモでも、アプリの更新を促す画面で画面右上にバツボタンが表示されており、そのボタンをクリックするとアップデートをキャンセルすることが可能です。
2つのアップデートの流れ
Google Play Core Libraryで実装できるアップデートの流れは、即時アップデートとフレキシブルアップデートのふた通りがあります。
即時アップデートはアップデートを促す画面が表示され、Updateボタンを押すとアプリの更新が始まり、更新中はアプリは使えません。更新が終わるとアプリが再起動され、更新されたアプリを使えるようになります。
フレキシブルアップデートはアップデートを促すダイアログが表示され、Updateを押すとバックグラウンドで更新ファイルのダウンロードが開始され、ダウンロード中はアプリは使えます。ダウンロードが完了するとアプリの更新が始まり、再起動後、更新されたアプリを使えるようになります。
できる限りユーザーにアプリを使い続けさせる、ということではフレキシブルアップデートの方がUXはいいのかもしれません。公式のAndroid developerのサイトでは重要でコアなアップデートは即時アップデート、そうでないならフレキシブルアップデートを、と勧めてますね。
今回は即時アップデートの実装方法を紹介したいと思います。
Google Play Core Libraryの導入
Google Play Core Libraryを使うので、ライブラリを使うことを宣言します。
アプリレベル(appディレクトリ直下)にあるbuild.gradleに以下の記述を追加してください。
(注)この投稿では全てkotlinでの実装を前提としています。
dependencies {
...
implementation("com.google.android.play:core:1.10.0")
implementation("com.google.android.play:core-ktx:1.8.1")
...
}
アプリ内アップデートを表示するコードを追加
アプリ内アップデートを表示するタイミングを検討してください。
弊社のアプリではアプリ起動時に表示されるActivityに実装しました。
下記をアプリ内アップデートを表示するタイミングに追加してください。
val appUpdateManager = AppUpdateManagerFactory.create(this) // thisはActivity
val appUpdateInfoTask = appUpdateManager.appUpdateInfo
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo: AppUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS // アプリ内アップデートが進行中の場合
|| appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) // 即時アップデートが可能な場合
) {
try {
// アプリ内アップデートを開始または再開
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.IMMEDIATE, // 即時アップデートを指定
this, // Activity
REQUEST_CODE_START_UPDATE_FLOW) // アプリ内アップデート画面からアプリへ戻ってきたときにonActivityResultで受け取るrequestcode。
} catch (e: SendIntentException) {
e.printStackTrace()
}
}
}
また、Activity#onActivityResultにアプリ内アップデート画面からアプリに戻ってきた時の処理を実装します。
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_CODE_START_UPDATE_FLOW -> if (resultCode != RESULT_OK) {
// アプリ内アップデートがキャンセルされたまたは失敗した場合
// 何もしない
}
else -> {}
}
}
これだけでアプリ内アップデートの画面は表示されます。
今後の改善
今回はシンプルに即時アップデートを表示する最低限の内容を書きました。
他にも、アップデートが公開されてからの経過日数や優先順位が高い場合にアプリ内アップデートにするなどの実装も可能ですので、今後対応していきたいと思います。
以上、簡単ですがアプリ内アップデートの実装方法でした。