本指南将介绍如何使用 Unity 在您的应用中支持应用内更新。我们针对使用 Kotlin 编程语言或 Java 编程语言以及原生代码 (C/C++) 完成实现的情况分别提供了指南。
设置您的开发环境
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,打开软件包管理器菜单。
将经理范围下拉菜单设置为选择我的注册库。
从软件包列表中选择 Google Play Integrity plugin for Unity 软件包,然后按 Install。
从 GitHub 导入
从 GitHub 下载最新的
.unitypackage
版本。导入
.unitypackage
文件,方法是依次选择 Unity 菜单选项 Assets > Import package > Custom Package,然后导入所有项目。
Unity SDK 概览
Play 应用内更新 API 是 Play Core SDK 系列的一部分。Unity 插件提供了一个 AppUpdateManager
类,用于处理您的应用与 Play API 之间的通信。您必须先实例化此类,然后才能使用此类来管理应用内更新:
AppUpdateManager appUpdateManager = new AppUpdateManager();
检查是否有可用更新
在请求更新之前,请检查您的应用是否有可用更新。使用 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(), etc. and decide whether to ask the user
// to start an in-app update.
}
else
{
// Log appUpdateInfoOperation.Error.
}
}
返回的 AppUpdateInfo
实例包含更新可用性状态。如果应用内更新已在进行中,该实例也会报告正在进行的更新的状态。
检查更新是否已过时
除了检查是否有可用更新之外,您可能还需要确定自您通过 Play 商店通知用户有更新以来已经过了多长时间。您可以根据这一信息来决定是允许用户灵活更新,还是立即发起更新。例如,您可能会等待几天,然后再通知用户进行灵活更新,在此之后再等待几天,然后再要求用户立即更新。
您可以使用 ClientVersionStalenessDays
检查自通过 Play 商店提供更新以来已经过了多少天:
var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;
检查更新优先级
借助 Google Play Developer API,您可以设置每项更新的优先级。这样,应用就可以决定向用户推荐更新的强烈程度。例如,可以考虑使用以下策略来设置更新优先级:
- 细微的界面改进:低优先级更新;既不请求灵活更新,也不请求立即更新。
- 性能提升:中优先级更新;请求灵活更新。
- 关键安全更新:高优先级更新;请求立即更新。
Google Play 使用 0 到 5 之间的整数值来确定优先级,其中 0 是默认值,5 代表最高优先级。如需设置更新的优先级,请使用 Google Play Developer API 中 Edits.tracks.releases
下的 inAppUpdatePriority
字段。发布版本中的所有新增版本都被视为与发布版本具有相同的优先级。只有在发布新版本时才能设置优先级,且以后无法更改。
按 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
对象是否指明允许使用选定的更新类型。
后续步骤
测试应用的应用内更新,以验证您的集成是否正常运行。