В этом руководстве описывается, как поддерживать обновления внутри вашего приложения с помощью Unity. Существуют отдельные руководства для случаев, когда ваша реализация использует язык программирования Kotlin или язык программирования Java , а также для случаев, когда ваша реализация использует собственный код (C/C++) .
Настройте среду разработки
OpenUPM-CLI
Если у вас установлен интерфейс командной строки OpenUPM, вы можете установить реестр OpenUPM с помощью следующей команды:
openupm add com.google.play.appupdate
ОпенУПМ
Откройте настройки менеджера пакетов , выбрав пункт меню Unity Edit > Project Settings > Package Manager .
Добавьте OpenUPM в качестве реестра с определенной областью в окно диспетчера пакетов:
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 «Окно» > «Диспетчер пакетов» .
Установите раскрывающийся список области менеджера, чтобы выбрать «Мои реестры» .
Выберите плагин Google Play Integrity для пакета Unity из списка пакетов и нажмите «Установить» .
Импорт из GitHub
Загрузите последнюю версию
.unitypackage
с GitHub.Импортируйте файл
.unitypackage
, выбрав пункт меню Unity «Активы» > «Импортировать пакет» > «Пользовательский пакет» и импортировав все элементы.
Обзор Unity SDK
API обновления внутри приложения Play входит в семейство 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 Store. Это может помочь вам решить, следует ли вам инициировать гибкое обновление или немедленное обновление. Например, вы можете подождать несколько дней, прежде чем уведомить пользователя о гибком обновлении, и еще несколько дней после этого, прежде чем требовать немедленного обновления.
Используйте ClientVersionStalenessDays
, чтобы проверить количество дней с момента, когда обновление стало доступно в Play Store:
var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;
Проверьте приоритет обновления
API разработчика Google Play позволяет вам устанавливать приоритет каждого обновления. Это позволяет вашему приложению решать, насколько настоятельно рекомендовать обновление пользователю. Например, рассмотрим следующую стратегию установки приоритета обновления:
- Незначительные улучшения пользовательского интерфейса: Обновление с низким приоритетом ; не запрашивайте ни гибкого обновления, ни немедленного обновления.
- Улучшения производительности: обновление среднего приоритета ; запросите гибкое обновление.
- Критическое обновление безопасности: Высокоприоритетное обновление; запросите немедленное обновление.
Для определения приоритета Google Play использует целое число от 0 до 5, где 0 — значение по умолчанию, а 5 — наивысший приоритет. Чтобы установить приоритет обновления, используйте поле inAppUpdatePriority
в разделе Edits.tracks.releases
в API разработчика Google Play. Все новые версии, добавленные в выпуск, имеют тот же приоритет, что и сам выпуск. Приоритет можно установить только при выпуске новой версии и нельзя изменить позже.
Установите приоритет с помощью 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()
не равен нулю. - Если
PlayAsyncOperation
возвращает код ошибкиErrorUpdateUnavailable
, убедитесь, что доступна обновленная версия приложения с тем же идентификатором приложения и ключом подписи. - Если
PlayAsyncOperation
возвращает код ошибкиErrorUpdateNotAllowed
, это означает, что объектAppUpdateOptions
указывает тип обновления, который не разрешен для доступного обновления. Прежде чем запускать поток обновлений, проверьте, указывает ли объектAppUpdateInfo
, что выбранный тип обновления разрешен.
Следующие шаги
Проверьте обновления внутри приложения, чтобы убедиться, что ваша интеграция работает правильно.