В этом руководстве рассказывается, как реализовать поддержку обновлений в приложении с помощью Unity. Существуют отдельные руководства для случаев, когда в вашей реализации используется язык программирования Kotlin или Java, и случаев, когда в вашей реализации используется нативный код (C/C++).
Обзор Unity SDK
Play In-App Update API входит в семейство Play Core SDK. Плагин Unity предлагает класс AppUpdateManager для обработки взаимодействия между вашим приложением и Google Play API. Чтобы управлять обновлениями в приложении, создайте экземпляр этого класса:
AppUpdateManager appUpdateManager = new AppUpdateManager();
Как настроить среду разработки
OpenUPM-CLI
Если у вас установлен OpenUPM CLI, вы можете установить реестр OpenUPM с помощью следующей команды:
openupm add com.google.play.appupdateOpenUPM
Откройте настройки менеджера пакетов, выбрав в меню 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
Скачайте последнюю версию
.unitypackageс сайта GitHub.Импортируйте файл
.unitypackage, выбрав в меню Unity Assets (Объекты) > Import package (Импортировать пакет) > Custom Package (Пользовательский пакет), и импортируйте все элементы.
Проверьте наличие обновлений
Прежде чем запрашивать обновление, проверьте, доступно ли оно для вашего приложения. Чтобы проверить наличие обновления в сопрограмме, используйте 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 позволяет задавать приоритет для каждого обновления. Это позволяет приложению решить, насколько настойчиво рекомендовать пользователю обновление. Например, можно использовать следующую стратегию:
- Незначительные улучшения интерфейса. Низкий приоритет. Не запрашивайте ни гибкое, ни немедленное обновление.
- Улучшение производительности. Средний приоритет. Запросите гибкое обновление.
- Критическое обновление системы безопасности – высокий приоритет, требуется немедленное обновление.
Для определения приоритета Google Play использует целое число от 0 до 5, где 0 – значение по умолчанию, а 5 – наивысший приоритет. Чтобы задать приоритет обновления, используйте поле inAppUpdatePriority в разделе Edits.tracks.releases в Google Play Developer API. Все новые версии в выпуске имеют тот же приоритет, что и сам выпуск. Приоритет можно задать только при выпуске новой версии, и его нельзя изменить позже.
Задайте приоритет с помощью Google Play Developer API, как описано в документации по Play Developer API. Приоритет обновления в приложении должен быть указан в ресурсе Edit.tracks, который передается в методе Edit.tracks: update. В примере ниже показан выпуск приложения с кодом версии 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. Прежде чем запускать процесс обновления, убедитесь, что объектAppUpdateInfo, возвращенный изGetAppUpdateInfo(), не равен null. - Если
PlayAsyncOperationвозвращает код ошибкиErrorUpdateUnavailable, убедитесь, что доступна обновленная версия приложения с тем же идентификатором приложения и ключом подписи. - Если метод
PlayAsyncOperationвозвращает код ошибкиErrorUpdateNotAllowed, это означает, что объектAppUpdateOptionsуказывает на тип обновления, который не разрешен для доступного обновления. Прежде чем запускать процесс обновления, проверьте, разрешен ли выбранный тип обновления в объектеAppUpdateInfo.
Дальнейшие действия
Протестируйте обновления в приложении, чтобы убедиться, что интеграция работает правильно.