アプリを利用しながらアプリの更新ができるin-app updates

Androidエンジニアの@sakebookです。 今まではストアに飛ばしたり、自前で用意したロジックやAPIで更新があるかを確認していました。しかしそんな時代はもう終わりました。Play Core Libraryを使えばアプリ内でアップデートが可能になります。

in-app updates

文字通りアプリ内でアプリのアップデートを行える機能です。アプリのアップデートといえば、知らない間に自動更新されていたり、ストアへ行って更新ボタンを押すなどがありましたが、それらのトリガーをアプリ内から任意のタイミングで引き起こすことが可能になったイメージです。

in-app updatesでは大きく分けて2つの方法がサポートされています。

フレキシブル(Flexible)

知らない間に自動更新

に相当するものです。ユーザにアプリを利用させつつ更新版アプリをDLし、DL完了したタイミングで再起動するメソッドを呼び出すことでアプリを再起動させられます。

アプリにとって必須とは言えないアップデート等の場合に有効です。

f:id:sakebook:20200826004435p:plain

即時(Immediate)

ストアへ行って更新ボタンを押す

に相当するものです。更新版アプリをDLしている間はユーザにアプリのUIを触らせない形になります。DL完了後、画面に従いアプリは自動で再起動します。

アプリにとって必須なアップデート等の場合に有効です。

f:id:sakebook:20200826004507p:plain

実装

詳細はドキュメントに任せます。

ざっくりいうと、アプデが可能かどうか確認し、可能であればFlexible or Immediateとしてアプデリクエストを送る流れです。

Flexibleの場合は、自動ではアプデ完了しないので、DLの進捗をモニタリングし、完了したら再起動を促すUIを表示するのが推奨されています。再起動自体はアプリをDL後、AppUpdateManager#completeUpdate()を呼び出すことで可能です。アプリがBGの状態で呼び出すとアップデートがサイレントインストールされます。

Immediateの場合は、全画面表示になりユーザのアプリの利用を阻害しますが、ユーザはキャンセルすることもできます。そのため、DLがキャンセルされた場合に途中から再開するべきか判定する処理があることが望ましいです。

どちらの場合でも、ユーザはキャンセル可能で、アップデートを強制させるものではないことに注意してください。

テスト

ロジックのテスト用にFakeAppUpdateManagerというクラスが用意されています。AppUpdateManagerと同様のinterfaceを持っています。状態を操作できることと、実際にDLやUIは表示させないこと以外は同じです。

初めての場合は実際にアプリがどんな挙動を取るのか確認したくなると思います。

そんなとき、Google Playの内部アプリ共有機能を使えば実際にin-app updatesを確認することも出来ます。

内部アプリ共有(internal app-sharing)

通常、ストアにあげるアプリにはVersionCodeをincrementしたりする必要がありますが、internal app-sharingを使えばincrementの制約を無視したり、許可リストによる配布が可能になります。

アプリをアップロードしてリンクを発行することで、認定テスターやリンクを知っている人のみDL可能にします。認定テスターとはメーリング リストに追加したテスターのことです。

注意点として、認定テスターはGooglePlayアプリの設定からバージョンを7回タップしてデベロッパー設定をしておく必要があります。設定をしていないと、発行したリンクを踏んでもDLできません。また、既存のアプリとは同じPackage Nameなので端末内で同居はできません。

認定テスターは発行したリンクを踏むことでストア内のinternal app-sharingのアプリページに遷移し、DLできるようになります。

in-app updatesは、GooglePlayアプリ上で更新があるかどうかでアプデ可能かを判定しています。internal app-sharingを使うと、既にストアに上がっているアプリとは別のアプリとして扱われます。

別のアプリとして扱われるというのは、更新判定が別という意味です。

例えばストアのアプリのVersion Codeが2で、internal app-sharingのアプリのVersion Codeを1にして、internal app-sharingのVersion Code1のアプリをインストールしていても更新判定は行われません。

f:id:sakebook:20200826004923p:plain

internal app-sharingのアプリで、Version Codeが2以上ものを用意し、そのリンクを踏んで、GooglePlayアプリ上で更新があることを認識させてあげることで、アプデ可能判定フラグを建てることが出来ます。

  • internal app-sharingのVersion Code 1のリンクを踏んでアプリをインストール
  • internal app-sharingのVersion Code 2のリンクを踏んで「更新」ボタンが確認できたら更新をせずストアから離れる
  • アプデ可能判定フラグが立つ
  • internal app-sharingのVersion Code 1のアプリでin-app updatesの実装をしている画面を表示
  • アプデ可能判定になりin-app updatesのフローに入る

f:id:sakebook:20200826004951p:plain

つまり、既存のストアアプリとは別で、バージョン違いの内部アプリ共有のアプリを2つ用意することで既存のストアアプリに影響を与えることなく実際にin-app updatesの確認ができます。

f:id:sakebook:20200826005325p:plain

任意の識別しやすい名前をつけることが出来ます。ニュースダイジェストではまだAndroid App Bundle(AAB)に対応していませんが、もちろんAABでも可能です。

ニュースダイジェストでは、Immediateの方式で実装しました。

ニュースダイジェストでは、ユーザ一人ひとりに対して返事を行うことは現状していません。しかしユーザからのフィードバックには目を通しています。

フィードバックの中には、アプリを最新版にしてもらえれば直っているものとか対応している機能があったりするのにと思うケースもちらほらあります。

そこで今回は、フィードバックを送る画面でin-app updatesを組み込むことにしました。そうすることで、現状送ろうとしていたフィードバックはアプデによって解決されるかもしれないことを示せるようにしました。

なので、FlexibleではなくてImmediateを選択しました。

もちろん内容によっては解決されないものもありますし、そもそもin-app updatesの仕組みを導入したバージョン以降でしか機能しないです。

f:id:sakebook:20200826005132p:plain

今回のような例の実装であれば、1日あればできるので、気になった方は仕組みとしては入れておくと良いと思います。

きめ細やかな制御

今回は利用しませんでしたが、ストアに更新可能なアプリが配布されてから何日経過しているかという情報や、Google Play Developer APIと組み合わせることでアプリのバージョンごとにアップデートのpriorityの設定が可能です。

更新が頻繁であったり、FlexibleとImmediateを組み合わせたい場合などに有効だと思います。

まとめ

開発者としてはなるべく最新のアプリを使ってもらいたいです。そうすることがユーザにとってもメリットです。

適切に更新導線を組み込むことで、ユーザにストレスなく最新のアプリを提供できるようになります。

in-app updatesはその選択肢の一つになるでしょう。

参考

アプリ内アップデートをサポートする  |  Android デベロッパー  |  Android Developers

Support in-app updates  |  Android Developers

Internal app sharing | Google Play Console

Exploring in-app updates on Android | by Joe Birch | Google Developers Experts | Medium

Support In-App-Updates Implementation Example | by Rajan Maurya | Medium

AppUpdateInfo  |  Android デベロッパー  |  Android Developers