Поддержка обновлений внутри приложения (Unity)

В этом руководстве описывается, как поддерживать обновления внутри приложения с помощью Unity. Существуют отдельные руководства для случаев, когда ваша реализация использует язык программирования Kotlin или Java , и для случаев, когда ваша реализация использует нативный код (C/C++) .

Обзор Unity SDK

API для обновления приложений в Play входит в семейство SDK Play Core . Плагин Unity предоставляет класс AppUpdateManager для обработки связи между вашим приложением и API Google Play. Перед использованием этого класса для управления обновлениями приложений необходимо его создать:

AppUpdateManager appUpdateManager = new AppUpdateManager();

Настройте среду разработки.

OpenUPM-CLI

Если у вас установлен OpenUPM CLI , вы можете установить реестр OpenUPM с помощью следующей команды:

openupm add com.google.play.appupdate

OpenUPM

  1. Откройте настройки менеджера пакетов , выбрав в меню Unity пункт «Редактировать» > «Настройки проекта» > «Менеджер пакетов» .

  2. Добавьте 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
    
  3. Откройте меню менеджера пакетов , выбрав в меню Unity пункт «Окно» > «Менеджер пакетов» .

  4. В раскрывающемся списке «Область действия менеджера» выберите «Мои реестры» .

  5. Выберите из списка пакетов плагин Google Play Integrity для Unity и нажмите «Установить» .

Импорт из GitHub

  1. Загрузите последнюю версию .unitypackage с GitHub.

  2. Импортируйте файл .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 содержит информацию о статусе доступности обновления. Если обновление приложения уже выполняется, экземпляр также сообщает о статусе текущего обновления.

Проверьте устарелость обновлений.

Помимо проверки наличия обновления, вам также может быть полезно узнать, сколько времени прошло с момента последнего уведомления пользователя об обновлении через Play Store. Это поможет вам решить, следует ли инициировать гибкое обновление или немедленное. Например, вы можете подождать несколько дней, прежде чем уведомить пользователя о гибком обновлении, и еще несколько дней после этого, прежде чем требовать немедленного обновления.

Используйте ClientVersionStalenessDays , чтобы проверить, сколько дней прошло с момента выхода обновления в Play Store:

var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;

Проверить приоритет обновления

API для разработчиков Google Play позволяет устанавливать приоритет каждого обновления. Это позволяет вашему приложению решать, насколько настоятельно рекомендовать пользователю обновление. Например, рассмотрим следующую стратегию установки приоритета обновлений:

  • Незначительные улучшения пользовательского интерфейса: обновление с низким приоритетом ; не запрашивать ни гибкое обновление, ни немедленное обновление.
  • Улучшения производительности: обновление со средним приоритетом ; запросите гибкое обновление.
  • Критическое обновление безопасности: обновление с высоким приоритетом ; запросите немедленное обновление.

Для определения приоритета 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 на то, что выбранный тип обновления разрешен.

Следующие шаги

Проверьте обновления внутри приложения, чтобы убедиться в корректной работе интеграции.