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

SDK обновлений для Flutter 6.1.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 разрешена установка приложений.

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

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

flutter pub add flutter_rustore_update

Эта команда добавит строчку в файл pubspec.yaml.

pubspec.yaml
dependencies:
flutter_rustore_update: ^6.1.0

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

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

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

RustoreUpdateClient.info().then((info) {
print(info);
}).catchError((err) {
print(err);
});
Объект info содержит набор параметров, необходимых для определения доступности обновления.

  • 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) — в ожидании.
к сведению

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

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

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

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

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

подсказка

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

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

RustoreUpdateClient.listener((state) {
switch (state.installStatus) {
case INSTALL_STATUS_DOWNLOADED:
// Обновление готово к установке
break;
case INSTALL_STATUS_DOWNLOADING:
// Здесь можно отобразить прогресс скачивания
break;
case INSTALL_STATUS_FAILED:
print("err ${state.installErrorCode}");
break;
}
});

Объект 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 — код ошибки во время скачивания. Коды ошибок описаны в разделе Обработка ошибок.

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

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

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

Для запуска скачивания обновления приложения вызовите метод download().

к сведению

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

RustoreUpdateClient.download().then((value) {
print("download code ${value.code}");
if (value.code == ACTIVITY_RESULT_CANCELED) {
// Пользователь отказался от скачивания
}
}).catchError((err) {
print("download err ${err}");
}
);

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

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

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

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

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

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

Для запуска скачивания принудительного обновления приложения вызовите метод immediate().

RustoreUpdateClient.immediate().then((value) {
print("silent code ${value.code}");
}).catchError((err) {
print("immediate err ${err}");
}
);

resultCode (Int):

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

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

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

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

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

Для запуска скачивания тихого обновления приложения вызовите метод silent().

RustoreUpdateClient.silent().then((value) {
print("silent code ${value.code}");
}).catchError((err) {
print("silent err ${err}");
}
);

При вызове then с code = ACTIVITY_RESULT_OK будет зарегистрирована задача на скачивание обновления.

В данном сценарии может быть вызван только then с ACTIVITY_RESULT_OK, либо catchError.

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

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

подсказка

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

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

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

  • completeUpdateFlexible() — обновление и перезапуск приложения;
  • completeUpdateSilent() — обновление и закрытие приложения.
подсказка

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

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

Вызов метода completeUpdateFlexible
RustoreUpdateClient.completeUpdateFlexible().catchError((err) {
print("completeUpdateFlexible err ${err}");
});

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

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

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

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

Вызов метода completeUpdateSilent
RustoreUpdateClient.completeUpdateSilent().catchError((err) {
print("completeUpdateSilent err ${err}");
});

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

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

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

Все ошибки в плагине реализованы константами. Описание констант в файле const.dart.

Список возможных ошибок

  • 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.