Перейти к основному содержимому

SDK обновлений приложений

Интеграция стороннего SDK для обновлений может значительно улучшить пользовательский опыт и упростить процесс управления обновлениями вашего приложения. Однако, как и с любой сторонней библиотекой, могут возникнуть определённые проблемы и вызовы. В этом руководстве мы рассмотрим, зачем вам может понадобиться интеграция такого SDK и какие проблемы могут возникнуть в процессе.

Зачем интегрировать стороннее SDK для обновлений?

  • Улучшение пользовательского опыта
    RuStore In-App Updates SDK, позволяет пользователям получать обновления без необходимости покидать приложение или заходить в магазин приложений. Это делает процесс обновления более плавным и удобным.
  • Повышение безопасности. Регулярные обновления могут включать исправления безопасности. Интеграция SDK для обновлений помогает убедиться, что пользователи всегда используют самую безопасную версию вашего приложения.
  • Быстрая доставка новых функций
    Сторонние SDK для обновлений позволяют быстро доставлять новые функции и улучшения пользователям. Это особенно важно для приложений, которые активно развиваются и требуют частых обновлений.
  • Снижение нагрузки на разработчиков
    Интеграция стороннего SDK для обновлений автоматизирует процесс проверки и установки обновлений, что снижает нагрузку на разработчиков и позволяет им сосредоточиться на улучшении функциональности приложения.

Интеграция SDK обновлений RuStore в приложение

Добавление зависимости

Добавление любого нового SDK начинается с добавления зависимости в ваше приложение.

    implementation("ru.rustore.sdk:appupdate:6.0.0")

Для работы с SDK обновлений нам нужен менеджер обновлений, создание менеджера обновлений.

val updateManager = RuStoreAppUpdateManagerFactory.create(context)

Условия работы SDK обновлений

Ниже представлены условия доступности работа SDK обновлений.

  • Приложение загружено в Консоль RuStore.
  • Приложение прошло модерацию (публиковать приложение необязательно).
Важно
  • Подпись тестируемой сборки (например, debug) приложения должна совпадать с подписью сборки приложения, которая была загружена в консоль и прошла модерацию ранее (например, release).
  • ОС Android версии 7.0 или выше.
  • Версия RuStore на устройстве пользователя актуальная.
  • Пользователь авторизован в RuStore.
  • Приложению RuStore разрешена установка приложений.

Проверка доступности SDK

Проверить доступность SDK можно с помощью метода getAppUpdateInfo().

В ответ мы получим объект AppUpdateInfo, который содержит в себе информацию об обновлении. Объект AppUpdateInfo содержит набор параметров, необходимых для определения доступности обновления.

  • updateAvailability — доступность обновления.
  • installStatus — статус установки обновления, если пользователь уже устанавливает обновление в текущий момент времени.
подсказка

Подробнее о статусах смотрите в документации.

Ниже представлен пример вызова метода getAppUpdateInfo().

ruStoreAppUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability == UpdateAvailability.UPDATE_AVAILABLE) {
// Обновление доступно(здесь можно зарегистрировать listener и начать загрузку)
}
}
.addOnFailureListener { throwable ->
Log.e(TAG, "getAppUpdateInfo error", throwable)
}

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

Для этого нам понадобится специальный слушатель статуса скачивания обновления registerListener.

Создание и использования слушателя.

ruStoreAppUpdateManager.registerListener { state ->
when (state.installStatus) {
InstallStatus.DOWNLOADED -> {
// Обновление готово к установке
}
InstallStatus.DOWNLOADING -> {
val totalBytes = state.totalBytesToDownload
val bytesDownloaded = state.bytesDownloaded
// Здесь можно отобразить прогресс скачивания
}
InstallStatus.FAILED -> {
Log.e(TAG, "Downloading error")
}
}
}
подсказка

Подробнее о статусах скачивания смотрите в документации.

Типы обновлений приложения

RuStore SDK обновлений предоставляет 3 типа обновлений:

  • FLEXIBLE (отложенное обновление);
  • SILENT (тихое обновление);
  • IMMEADIATE (принудительное обновление).

FLEXIBLE (отложенное обновление)

Самый распространённый тип и привычный пользователям сценарий:

  1. пользователю будет показан диалог с UI от RuStore для подтверждения обновления;
  2. при нажатии на кнопку Обновить покажется диалоговое окно для подтверждения установки обновления;
  3. после завершения установки приложение закроется.

Ниже представлен пример вызова FLEXIBLE обновления.

startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().appUpdateType(FLEXIBLE).build())

SILENT (тихое обновление)

Обновления без UI (шторки) RuStore с предложением обновиться — пользователю останется только подтвердить установку:

  1. пользователю будет показано диалоговое окно для подтверждения установки обновления (обновление будет скачано в фоне);
  2. после завершения установки приложение закроется.

Ниже представлен пример вызова SILENT обновления.

startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().appUpdateType(SILENT).build())

IMMEADIATE (принудительное обновление)

Если с типами обновлений выше всё просто и понятно, то принудительное обновление требует отдельного внимания.

Рассмотрим, зачем нам вообще третий тип обновления, «ломающий» пользовательский опыт взаимодействия с приложением.

В разработке мобильных приложений есть такое понятие, как «хвост старых версий». Допустим, вы выпускаете первую версию приложения, а через год у вас уже версия с массой исправлений и нововведений, которые делались с ориентировкой на пользователей.

Но смотря логи сервера или статистику в «крашлитике», вы можете заметить, что часть пользователей всё ещё пользуется первой версией вашего продукта.

Казалось бы, пусть пользуются, раз их всё устраивает. Но есть 2 основные проблемы, для решения которых нужно прибегнуть к принудительному обновлению приложения:

  1. Баги, баги и ещё раз баги.
    Каждый день мы видим пользователей со старой версией приложения и багом, который пофиксили в следующих версиях. Иногда это может быть какой-то критический для продукта баг, который срочно надо устранить у пользователя.
  2. Внедрение новых фич.
    В новых версиях приложения добавлена функциональность, могут быть важны данные аналитики или доход, который эта функциональность приносит — вот только пользователи не торопятся обновляться, и приходится ждать. При таком ожидании вы можете терять время и деньги.

Для решения таких проблем и существует механизм принудительного обновления. Рассмотрим, как его использовать в приложении.

После получения AppUpdateInfo вы можете проверить доступность принудительного обновления.

if (appUpdateInfo.isUpdateTypeAllowed(IMMEDIATE)) {
// Принудительное обновление доступно
}

Результат функции isUpdateTypeAllowed рекомендуется использовать для принятия решения о запуске принудительного обновления, но этот результат не влияет на возможность запуска сценария. Необходимость запуска сценария обновления может происходить по вашей внутренней логике.

 startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().appUpdateType(IMMEADIATE).build())

При успешном обновлении дальнейших действий не требуется.

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

Для этого вызовите метод completeUpdate(appUpdateOptions: AppUpdateOptions). В этот метод можно передавать только 2 типа завершения установки — FLEXIBLE и SILENT: отложенное и тихое обновление соответственно.

completeUpdate(AppUpdateOptions.Builder().appUpdateType(AppUpdateType.FLEXIBLE).build())
  • Если передать тип обновлений FLEXIBLE, приложение перезапустится.
  • Если передать тип обновлений SILENT, приложение закроется без перезапуска.