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

10.5.2

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

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

Изменено​

Ссылка на maven-репозиторий

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

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

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

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

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

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

  • Загружены данные о приложении в разделе Push-уведомления > Проекты из RuStore Консоль.
  • Приложение прошло модерацию (публиковать приложение необязательно).
Важно

Подпись и package name различных типов сборок вашего приложения (debug, release и т.д.) могут отличаться друг от друга. В таком случае вы должны создать в разделе Push-уведомления > Проекты из RuStore Консоль проект под каждый тип сборки.

  • ОС Android версии 7.0 или выше.
  • Версия RuStore на устройстве пользователя актуальная.
  • Пользователь авторизован в RuStore.
  • Приложению RuStore разрешена установка приложений.

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

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

flutter pub add flutter_rustore_update

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

pubspec.yaml
dependencies:
flutter_rustore_update: ^10.5.0

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

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

  • На устройстве пользователя установлена актуальная версия RuStore.
  • Пользователь и приложение не должны быть заблокированы в RuStore.

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

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

  • updateAvailability — доступность обновления:

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

    • INSTALL_STATUS_UNKNOWN (int == 0) — по умолчанию;
    • INSTALL_STATUS_DOWNLOADED (int == 1) — скачано;
    • INSTALL_STATUS_DOWNLOADING (int == 2) — скачивается;
    • INSTALL_STATUS_FAILED (int == 3) — ошибка;
    • INSTALL_STATUS_INSTALLING (int == 4) — выполняется установка;
    • INSTALL_STATUS_PENDING (int == 5) — в ожидании.

Пакет также предоставляет type-safe представление этих значений:

  • info.updateAvailabilityValue — значение типа UpdateAvailability;
  • info.installStatusValue — значение типа InstallStatus.

Пример:

RustoreUpdateClient.info().then((info) {
if (info.updateAvailabilityValue == UpdateAvailability.available) {
print('Обновление доступно');
}
});
К сведению

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

Примечание

Для обратной совместимости в пакете сохранены legacy-константы UPDATE_AILABILITY_*. Для новых интеграций рекомендуется использовать UPDATE_AVAILABILITY_*.

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

Отслеживание статуса обновления​

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

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

подсказка

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

Используйте RustoreUpdateClient.stateStream.

import 'dart:async';

late final StreamSubscription<RequestResponse> updateSubscription;


void initState() {
super.initState();

updateSubscription = RustoreUpdateClient.stateStream.listen((state) {
switch (state.installStatusValue) {
case InstallStatus.downloaded:
// Обновление готово к установке
break;
case InstallStatus.downloading:
// Здесь можно отобразить прогресс скачивания
print('progress: ${state.downloadProgress}');
break;
case InstallStatus.failed:
print('err ${state.installError.description}');
break;
default:
break;
}
});
}


void dispose() {
updateSubscription.cancel();
super.dispose();
}

stateStream возвращает broadcast Stream<RequestResponse> и подходит для безопасной работы с жизненным циклом экрана или сервиса. После отмены подписки через cancel() поток событий перестает поступать в приложение.

Для обратной совместимости также сохранен метод listener(callback), однако для новых интеграций рекомендуется использовать именно stateStream.

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

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

    • INSTALL_STATUS_UNKNOWN (int == 0) — по умолчанию;
    • INSTALL_STATUS_DOWNLOADED (int == 1) — скачано;
    • INSTALL_STATUS_DOWNLOADING (int == 2) — скачивается;
    • INSTALL_STATUS_FAILED (int == 3) — ошибка;
    • INSTALL_STATUS_INSTALLING (int == 4) — выполняется установка;
    • INSTALL_STATUS_PENDING (int == 5) — в ожидании.
  • bytesDownloaded — количество загруженных байт;

  • totalBytesToDownload — общее количество байт, которое необходимо скачать;

  • installErrorCode — код ошибки во время скачивания. Коды ошибок описаны в разделе Обработка ошибок.

Пакет также предоставляет дополнительные свойства:

  • state.installStatusValue — значение типа InstallStatus;
  • state.installError — значение типа RustoreUpdateError;
  • state.downloadProgress — прогресс скачивания в диапазоне от 0.0 до 1.0, если общий размер загрузки известен.

Пример отображения прогресса скачивания:

RustoreUpdateClient.stateStream.listen((state) {
if (state.installStatusValue == InstallStatus.downloading) {
print('Downloaded: ${state.bytesDownloaded}/${state.totalBytesToDownload}');
print('Progress: ${state.downloadProgress}');
}
});
ОБРАТИТЕ ВНИМАНИЕ

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

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

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

  • Пользователь начал скачивание обновления, но отменил скачивание — в этом случае:
    • updateAvailability — UPDATE_AVAILABILITY_AVAILABLE (2);
    • installStatus — INSTALL_STATUS_UNKNOWN (0).
  • Пользователь скачал файл обновления, но не стал его устанавливать — в этом случае:
    • updateAvailability — UPDATE_AVAILABILITY_AVAILABLE (2);
    • installStatus — INSTALL_STATUS_DOWNLOADED (1).
Примечание

Метод RustoreUpdateClient.listener(callback) сохранен для обратной совместимости. Для новых интеграций рекомендуется использовать RustoreUpdateClient.stateStream.

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

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

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

Для запуска скачивания обновления приложения вызовите метод 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 или значения InstallStatus.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.

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

После получения статуса INSTALL_STATUS_DOWNLOADED или значения InstallStatus.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.

Дополнительно пакет предоставляет type-safe представление ошибок:

  • RustoreUpdateError;
  • state.installError;
  • state.installError.description.

Пример обработки ошибки скачивания:

RustoreUpdateClient.stateStream.listen((state) {
if (state.installStatusValue == InstallStatus.failed) {
print(state.installError.description);
}
});
Примечание

Метод RustoreUpdateClient.listener(callback) сохранен для обратной совместимости. Для новых интеграций рекомендуется использовать RustoreUpdateClient.stateStream.

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

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