このガイドでは、Unity を使用してアプリ内でアプリ内アップデートをサポートする方法について説明します。実装に Kotlin プログラミング言語または Java プログラミング言語を使用するケースと、ネイティブ コード(C/C++)を使用するケースについては、個別のガイドが用意されています。
Unity SDK の概要
Play アプリ内アップデート API は Play Core SDK ファミリーの一部です。Unity プラグインには、アプリと Google Play API 間の通信を処理する AppUpdateManager
クラスが用意されています。このクラスを使用してアプリ内アップデートを管理するには、このクラスをインスタンス化する必要があります。
AppUpdateManager appUpdateManager = new AppUpdateManager();
開発環境をセットアップする
OpenUPM-CLI
OpenUPM CLI がインストールされている場合は、次のコマンドを使用して OpenUPM レジストリをインストールできます。
openupm add com.google.play.appupdate
OpenUPM
Unity のメニュー オプション [Edit] > [Project Settings] > [Package Manager] を選択して、パッケージ マネージャーの設定を開きます。
OpenUPM をスコープ付きレジストリとして Package Manager ウィンドウに追加します。
Name: package.openupm.com URL: https://package.openupm.com Scopes: com.google.external-dependency-manager com.google.play.common com.google.play.core com.google.play.appupdate
Unity メニュー オプションの [Window] > [Package Manager] を選択して、Package Manager メニューを開きます。
マネージャー スコープのプルダウンで [My Registries] を選択します。
パッケージ リストから Google Play Integrity plugin for Unity パッケージを選択し、[Install] を押します。
GitHub からインポートする
GitHub から最新の
.unitypackage
リリースをダウンロードします。Unity メニュー オプションの [Assets] > [Import Package] > [Custom Package] を選択、すべてのアイテムをインポートして、
.unitypackage
ファイルをインポートします。
アップデートの有無の確認
アップデートをリクエストする前に、アプリに適用できるアップデートが存在するかどうかを確認します。AppUpdateManager
を使用して、コルーチンでアップデートの有無を確認します。
IEnumerator CheckForUpdate()
{
PlayAsyncOperation<AppUpdateInfo, AppUpdateErrorCode> appUpdateInfoOperation =
appUpdateManager.GetAppUpdateInfo();
// Wait until the asynchronous operation completes.
yield return appUpdateInfoOperation;
if (appUpdateInfoOperation.IsSuccessful)
{
var appUpdateInfoResult = appUpdateInfoOperation.GetResult();
// Check AppUpdateInfo's UpdateAvailability, UpdatePriority,
// IsUpdateTypeAllowed(), ... and decide whether to ask the user
// to start an in-app update.
}
else
{
// Log appUpdateInfoOperation.Error.
}
}
返される AppUpdateInfo
インスタンスには、アップデートの有無を示すステータスが含まれます。アプリ内アップデートがすでに進行中の場合は、進行中のアップデートのステータスも報告されます。
アップデートの新しさの確認
アップデートが適用可能であるかどうかを確認するだけでなく、ユーザーが Google Play ストアからアップデートの通知を受信してから経過した期間を確認することもできます。これは、フレキシブル アップデートと即時アップデートのどちらを開始したらよいかを判断する際に有用です。たとえば、ユーザーにフレキシブル アップデートを通知するまで数日待ち、その後、即時アップデートを要求するまでさらに数日待つこともできます。
ClientVersionStalenessDays
を使用して、Google Play ストアからのアップデートの入手が可能になった時点から経過した日数を確認します。
var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;
アップデートの優先度の確認
Google Play Developer API を使用すると、各アップデートの優先度を設定できます。これにより、アプリはユーザーへの更新の推奨度を決定できます。たとえば、アップデートの優先度を設定するための次のような戦略を考えてみます。
- UI の小さな改善: 優先度が低いアップデート。フレキシブル アップデート、即時アップデートのいずれもリクエストしません。
- パフォーマンスの改善: 優先度が中程度のアップデート。フレキシブル アップデートをリクエストします。
- 重要なセキュリティ アップデート: 優先度が高いアップデート。即時アップデートをリクエストします。
優先度を決定するにあたり、Google Play は 0~5 の整数値を使用します。0 はデフォルトの値、5 は優先度が最も高い値です。アップデートの優先度を設定するには、Google Play Developer API の Edits.tracks.releases
の下にある inAppUpdatePriority
フィールドを使用します。リリースで新たに追加されたすべてのバージョンの優先度は、リリースと同じとみなされます。優先度は新しいリリースの公開時にのみ設定できます。後から変更することはできません。
Google Play Developer API を使用した優先度の設定については、Google Play Developer API のドキュメントをご覧ください。アプリ内アップデートの優先度は、Edit.tracks: update
メソッドで渡される Edit.tracks
リソースで指定する必要があります。次の例に、アプリ(バージョン コード 88、inAppUpdatePriority
5)のリリースを示します。
{ "releases": [{ "versionCodes": ["88"], "inAppUpdatePriority": 5, "status": "completed" }] }
アプリのコードで、UpdatePriority
を使用して特定のアップデートの優先度を確認できます。
var priority = appUpdateInfoOperation.UpdatePriority;
アップデートの開始
アップデートが利用可能であることを確認したら、AppUpdateManager.StartUpdate()
を使用してアップデートをリクエストできます。更新をリクエストする前に、最新の AppUpdateInfo
オブジェクトがあることを確認します。また、更新フローを構成するために AppUpdateOptions
オブジェクトも作成する必要があります。
次の例では、即時アップデート フロー用の AppUpdateOptions
オブジェクトを作成します。
// Creates an AppUpdateOptions defining an immediate in-app
// update flow and its parameters.
var appUpdateOptions = AppUpdateOptions.ImmediateAppUpdateOptions();
次の例では、フレキシブル アップデート フロー用の AppUpdateOptions
オブジェクトを作成します。
// Creates an AppUpdateOptions defining a flexible in-app
// update flow and its parameters.
var appUpdateOptions = AppUpdateOptions.FlexibleAppUpdateOptions();
AppUpdateOptions
オブジェクトには AllowAssetPackDeletion
フィールドも含まれており、デバイスのストレージが限られている場合に、アップデートによるアセットパックの消去を許可するかどうかを定義します。このフィールドはデフォルトで false
に設定されていますが、代わりにオプションの allowAssetPackDeletion
引数を ImmediateAppUpdateOptions()
または FlexibleAppUpdateOptions()
に渡して、true
に設定することもできます。
// Creates an AppUpdateOptions for an immediate flow that allows
// asset pack deletion.
var appUpdateOptions =
AppUpdateOptions.ImmediateAppUpdateOptions(allowAssetPackDeletion: true);
// Creates an AppUpdateOptions for a flexible flow that allows asset
// pack deletion.
var appUpdateOptions =
AppUpdateOptions.FlexibleAppUpdateOptions(allowAssetPackDeletion: true);
次のステップは、フレキシブル アップデートと即時アップデートのどちらをリクエストするかによって異なります。
フレキシブル アップデートの処理
最新の AppUpdateInfo
オブジェクトと適切に構成された AppUpdateOptions
オブジェクトを取得したら、AppUpdateManager.StartUpdate()
を呼び出して非同期でアップデート フローをリクエストできます。
IEnumerator StartFlexibleUpdate()
{
// Creates an AppUpdateRequest that can be used to monitor the
// requested in-app update flow.
var startUpdateRequest = appUpdateManager.StartUpdate(
// The result returned by PlayAsyncOperation.GetResult().
appUpdateInfoResult,
// The AppUpdateOptions created defining the requested in-app update
// and its parameters.
appUpdateOptions);
while (!startUpdateRequest.IsDone)
{
// For flexible flow,the user can continue to use the app while
// the update downloads in the background. You can implement a
// progress bar showing the download status during this time.
yield return null;
}
}
フレキシブル アップデート フローでは、ダウンロードが正常に完了した後、アプリのアップデートのインストールをトリガーする必要があります。そのためには、次の例に示すように AppUpdateManager.CompleteUpdate()
を呼び出します。
IEnumerator CompleteFlexibleUpdate()
{
var result = appUpdateManager.CompleteUpdate();
yield return result;
// If the update completes successfully, then the app restarts and this line
// is never reached. If this line is reached, then handle the failure (e.g. by
// logging result.Error or by displaying a message to the user).
}
即時アップデートの処理
最新の AppUpdateInfo
オブジェクトと適切に構成された AppUpdateOptions
オブジェクトを取得したら、AppUpdateManager.StartUpdate()
を呼び出して非同期でアップデート フローをリクエストできます。
IEnumerator StartImmediateUpdate()
{
// Creates an AppUpdateRequest that can be used to monitor the
// requested in-app update flow.
var startUpdateRequest = appUpdateManager.StartUpdate(
// The result returned by PlayAsyncOperation.GetResult().
appUpdateInfoResult,
// The AppUpdateOptions created defining the requested in-app update
// and its parameters.
appUpdateOptions);
yield return startUpdateRequest;
// If the update completes successfully, then the app restarts and this line
// is never reached. If this line is reached, then handle the failure (for
// example, by logging result.Error or by displaying a message to the user).
}
即時アップデート フローの場合、Google Play にはユーザーの確認ダイアログが表示されます。ユーザーがリクエストを承認すると、Google Play はアップデートのダウンロードとインストールを自動的に行い、インストールが成功すると更新後のバージョンでアプリを再起動します。
エラー処理
このセクションでは、一般的なエラーに対する解決策について説明します。
StartUpdate()
がArgumentNullException
をスローした場合は、AppUpdateInfo
が null であることを示しています。アップデート フローを開始する前に、GetAppUpdateInfo()
から返されたAppUpdateInfo
オブジェクトが null でないことを確認してください。PlayAsyncOperation
からErrorUpdateUnavailable
エラーコードが返された場合は、同じアプリケーション ID と署名鍵を持つアプリの更新バージョンが存在することを確認してください。PlayAsyncOperation
からErrorUpdateNotAllowed
エラーコードが返された場合、AppUpdateOptions
オブジェクトが、利用可能なアップデートで許可されていない更新タイプを示していることを意味します。アップデート フローを開始する前に、選択したアップデート タイプが許可されていることをAppUpdateInfo
オブジェクトが示しているかどうかを確認してください。
次のステップ
アプリのアプリ内アップデートをテストして、統合が正しく機能していることを確認します。