Skip to main content

6.0.0

Общие сведения

RuStore In-app updates SDK поддерживает актуальную версию приложения на устройстве пользователя. Это помогает пользователю увидеть обновления, оценить улучшение производительности и результат исправления ошибок.

Пример реализации

Используйте RuStore In-app updates SDK для реализации различных способов обновлений. В настоящий момент поддерживаются: отложенное, тихое (без UI от RuStore) и принудительное обновление.

Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать SDK обновлений.

Пользовательские сценарии

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

Для работы RuStore In-app updates SDK необходимо соблюдение следующих условий.

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

Подключение в проект

Для подключения скачайте RuStore AppUpdate SDK и импортируйте его в проект (Assets > Import Package > Custom Package). Зависимости подключаются автоматически с помощью External Dependency Manager (включен в SDK).

tip

Если вы используете операционную систему macOS, измените настройки утилиты архивации. В настройках Archive Utility снимите флажок Keep expanding if possible. В противном случае архив проекта будет скачан некорректно.

Также вы можете склонировать код с помощью Git.

Для корректной обработки зависимостей SDK выполните следующие настройки.

  1. Откройте настройки проекта: Edit > Project Settings > Player > Android Settings.

  2. В pазделе Publishing Settings включите следующие настройки.

    • Custom Main Manifest.
    • Custom Main Gradle Template.
    • Custom Gradle Properties Template.
  3. В разделе Other Settings настройте:

    • package name.
    • Minimum API Level = 24.
    • Target API Level = 34.
  4. Откройте настройки External Dependency Manager: Assets > External Dependency Manager > Android Resolver > Settings, включите следующие настройки.

    • Use Jetifier.
    • Patch mainTemplate.gradle.
    • Patch gradleTemplate.properties.
  5. Обновите зависимости проекта: Assets > External Dependency Manager > Android Resolver > Force Resolve.

Создание менеджера обновлений

Перед вызовом методов библиотеки необходимо создать менеджер обновлений.

RuStoreAppUpdateManager.Instance.Init();

Проверка наличия обновлений

Прежде чем запрашивать обновление, проверьте, доступно ли обновление для вашего приложения. Для проверки наличия обновлений вызовите метод getAppUpdateInfo(). При вызове данного метода проверяются следующие условия.

  • На устройстве пользователя установлена актуальная версия RuStore.
  • Пользователь и приложение не должны быть заблокированы в RuStore.
  • Приложению RuStore разрешена установка приложений.
  • Пользователь авторизован в RuStore.
В ответ на данный метод вы получите объект AppUpdateInfo, который будет содержать в себе информацию о необходимости обновления. Запросите этот объект заранее и закэшируйте его, чтобы запросить у пользователя запуск скачивания обновления без задержки и в удобный для пользователя момент времени.

RuStoreAppUpdateManager.Instance.GetAppUpdateInfo(
onFailure: (error) => {
// Handle error
},
onSuccess: (info) => {
// Process update info
}
);
Объект AppUpdateInfo содержит набор параметров, необходимых для определения доступности обновления.
  • updateAvailability — доступность обновления:

    • UNKNOWN (int == 0) — по умолчанию;
    • UPDATE_NOT_AVAILABLE (int == 1) — обновление не нужно;
    • UPDATE_AVAILABLE (int == 2) — обновление требуется загрузить или обновление уже загружено на устройство пользователя;
    • DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS (int == 3) — обновление уже скачивается или установка уже запущена.
  • installStatus — статус установки обновления, если пользователь уже устанавливает обновление в текущий момент времени:

    • UNKNOWN (int == 0) — по умолчанию;
    • DOWNLOADED (int == 1) — скачано;
    • DOWNLOADING (int == 2) — скачивается;
    • FAILED (int == 3) — ошибка;
    • PENDING (int == 5) — в ожидании.
info

Запуск скачивания обновления возможен только в том случае, если поле updateAvailability содержит значение UPDATE_AVAILABLE.

Скачивание и установка обновлений

Использование слушателя

После подтверждения доступности обновления (AppUpdateInfo) вы можете запросить статус скачивания обновления — для этого запустите слушатель статуса скачивания обновления.

Проверка статуса скачивания обновления

Используйте метод RegisterListener().

RuStoreAppUpdateManager.Instance.RegisterListener(listener);

listener — объект класса, реализующего интерфейс IInstallStateUpdateListener:

public interface IInstallStateUpdateListener {
public void OnStateUpdated(InstallState state);
}

Объект state описывает текущий статус скачивания. Ниже представлено содержимое объекта.

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

    • UNKNOWN (int == 0) — по умолчанию;
    • DOWNLOADED (int == 1) — скачано;
    • DOWNLOADING (int == 2) — скачивается;
    • FAILED (int == 3) — ошибка;
    • PENDING (int == 5) — в ожидании;
ОБРАТИТЕ ВНИМАНИЕ

В SDK обновлений нет особого статуса для ситуации, когда пользователь отменил скачивание обновления. Если пользователь прервал обновление на этапе скачивания, installStatus возвращает исходный статус UNKNOWN (0) с кнопкой Скачать.

Если пользователь уже скачал обновление, но отменил установку, то installStatus вернёт значение DOWNLOADED (1).

Рассмотрим следующие варианты.

  • Пользователь начал скачивание обновления, но отменил скачивание — в этом случае:
    • updateAvailabilityUPDATE_AVAILABLE (2);
    • installStatusUNKNOWN (0).
  • Пользователь скачал файл обновления, но не стал его устанавливать — в этом случае:
    • updateAvailabilityUPDATE_AVAILABLE (2);
    • installStatusDOWNLOADED (1).
  • bytesDownloaded — количество загруженных байт;
  • totalBytesToDownload — общее количество байт, которое необходимо скачать;
  • installErrorCode — код ошибки во время скачивания. Коды ошибок описаны в разделе Обработка ошибок.

Удаление слушателя

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

RuStoreAppUpdateManager.Instance.UnregisterListener(listener);

Запуск скачивания обновления

Отложенное обновление

Запуск сценария обновления

Для запуска скачивания обновления приложения вызовите метод StartUpdateFlow с параметром UpdateType.FLEXIBLE:

RuStoreAppUpdateManager.Instance.StartUpdateFlow(
UpdateType.FLEXIBLE,
onFailure: (error) => {
// Handle error
},
onSuccess: (resultCode) => {
// Handle flow result
}
);
info

Объект AppUpdateInfo после однократного использования становится невалидным. Для повторного вызова метода StartUpdateFlow() запросите AppUpdateInfo, снова используя метод GetAppUpdateInfo().

Если пользователь подтвердил скачивание обновления, тогда resultCode = UpdateFlowResult.RESULT_OK, если отказался, то resultCode = UpdateFlowResult.RESULT_CANCELED.

После получения статуса InstallStatus.DOWNLOADED вы можете вызвать метод установки обновления CompleteUpdate().

Рекомендуется уведомить пользователя о готовности обновления к установке.

Метод может вернуть ошибку.

Принудительное обновление

Запуск сценария обновления

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

var isImmediateUpdateAllowed = RuStoreAppUpdateManager.Instance.IsImmediateUpdateAllowed();

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

Для запуска сценария обновления используйте метод StartUpdateFlow с параметром UpdateType.IMMEDIATE:

RuStoreAppUpdateManager.Instance.StartUpdateFlowImmediate(
UpdateType.IMMEDIATE,
onFailure: (error) => {
// Handle error
},
onSuccess: (resultCode) => {
// Handle flow result
}
);

resultCode (Int):

  • UpdateFlowResult.RESULT_OK (-1) — обновление выполнено, код может не быть получен, т. к. приложение в момент обновления завершается.
  • UpdateFlowResult.RESULT_CANCELED (0) — флоу прервано пользователем, или произошла ошибка. Предполагается, что при получении этого кода следует завершить работу приложения.
  • UpdateFlowResult.RESULT_ACTIVITY_NOT_FOUND (2) — RuStore не установлен, либо установлена версия, которая не поддерживает принудительное обновление (RuStore versionCode < 191).

throwable - ошибка старта сценария обновления.

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

Тихое обновление

Запуск сценария обновления

Для запуска скачивания обновления приложения необходимо вызвать метод StartUpdateFlow с параметром UpdateType.SILENT.

RuStoreAppUpdateManager.Instance.StartUpdateFlowSilent(
UpdateType.SILENT,
onFailure: (error) => {
// Handle error
},
onSuccess: (resultCode) => {
// Handle flow result
}
);

При вызове onSuccess с resultCode = UpdateFlowResult.RESULT_OK будет зарегистрирована задача на скачивание обновления.

В данном сценарии может быть вызван только onSuccess с resultCode = UpdateFlowResult.RESULT_OK, либо onFailure.

После вызова метода вы можете следить за статусом скачивания обновления в слушателе.

После получения статуса InstallStatus.DOWNLOADED вы можете вызвать метод установки обновления CompleteUpdate(). Рекомендуется уведомить пользователя о готовности обновления к установке.

tip

Для тихого обновления рекомендуется реализовать свой интерфейс.

Установка обновления

Для запуска установки обновления используйте метод CompleteUpdate. Обновление происходит через нативный инструмент Android.

tip

Рекомендуется уведомить пользователя о готовности обновления к установке.

Гибкое завершение обновления

Обновление с UI от RuStore:

img
  1. Пользователю будет показан UI-диалог завершения обновления.

  2. В случае успешного обновления приложение будет перезапущено.

Метод CompleteUpdate должен быть вызван с параметром FLEXIBLE.

RuStoreAppUpdateManager.Instance.CompleteUpdate(
UpdateType.FLEXIBLE,
onFailure: (error) => {
// Handle error
}
);

UpdateType — тип процедуры завершения обновления:

  • FLEXIBLE — обновление и перезапуск приложения.

Тихое завершение обновления

Обновление без UI от RuStore:

  1. UI-диалог завершения обновления не будет показан.
  2. В случае успешного обновления приложение будет закрыто.

Метод CompleteUpdate должен быть вызван с параметром SILENT.

RuStoreAppUpdateManager.Instance.CompleteUpdate(
UpdateType.SILENT,
onFailure: (error) => {
// Handle error
}
);

UpdateType — тип процедуры завершения обновления:

  • SILENT — обновление и закрытие приложения.

Обработка ошибок

tip

Если вы получили в ответ onFailure, не рекомендуется самостоятельно отображать ошибку пользователю. Отображение ошибки может негативно повлиять на пользовательский опыт.

Ниже представлена структура ошибки.

public class RuStoreError {
public string name;
public string description;
}

Возможные ошибки

  • RuStoreNotInstalledException — на устройстве пользователя не установлен RuStore;
  • RuStoreOutdatedException — версия RuStore, установленная на устройстве пользователя, не поддерживает данный SDK;
  • RuStoreUserUnauthorizedException — пользователь не авторизован в RuStore;
  • RuStoreException — базовая ошибка RuStore, от которой наследуются остальные ошибки;
  • RuStoreInstallException(public val code: Int) — ошибка скачивания и установки.
    • ERROR_UNKNOWN(Int = 4001) — неизвестная ошибка.
    • ERROR_DOWNLOAD(Int = 4002) — ошибка при скачивании.
    • ERROR_BLOCKED(Int = 4003) — установка заблокированна системой.
    • ERROR_INVALID_APK(Int = 4004) — некорректный APK обновления.
    • ERROR_CONFLICT(Int = 4005) — конфликт с текущей версией приложения.
    • ERROR_STORAGE(Int = 4006) — недостаточно памяти на устройстве.
    • ERROR_INCOMPATIBLE(Int = 4007) — несовместимо с устройством.
    • ERROR_APP_NOT_OWNED(Int = 4008) — приложение не куплено.
    • ERROR_INTERNAL_ERROR(Int = 4009) — внутренняя ошибка.
    • ERROR_ABORTED(Int = 4010) — пользователь отказался от установки обновления.
    • ERROR_APK_NOT_FOUND(Int = 4011) — APK для запуска установки не найден.
    • ERROR_EXTERNAL_SOURCE_DENIED(Int = 4012) — запуск обновления запрещён. Например, в первом методе вернулся ответ о том, что обновление недоступно, но пользователь вызывает второй метод.
    • ERROR_ACTIVITY_SEND_INTENT(Int = 9901) — ошибка отправки intent на открытие активити.
    • ERROR_ACTIVITY_UNKNOWN(Int = 9902) — неизвестная ошибка отрытия активити.

Список зависимостей для обновления приложения

  • ru.rustore.sdk:core:0.1.10 — GNU Lesser General Public License v3.0;
  • ru.rustore.sdk:analytics:0.1.5 — GNU Lesser General Public License v3.0;
  • org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20 — The Apache Software License, Version 2.0;
  • org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 — The Apache Software License, Version 2.0;
  • androidx.core:core-ktx:1.9.0 — The Apache Software License, Version 2.0;
  • androidx.appcompat:appcompat:1.5.1 — The Apache Software License, Version 2.0;
  • androidx.activity:activity:1.5.1 — The Apache Software License, Version 2.0.