7.0.0
Общие сведения
RuStore In-app updates SDK поддерживает актуальную версию приложения на устройстве пользователя. Это помогает пользователю увидеть обновления, оценить улучшение производительности и результат исправления ошибок.
Пример реализации
Используйте RuStore In-app updates SDK для реализации различных способов обновлений. В настоящий момент поддерживаются: отложенное, тихое (без UI от RuStore) и принудительное обновление.
- Kotlin
- Java
Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать SDK обновлений.
Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать SDK обновлений.
Пользовательские сценарии
- Отложенное обновление
- Принудительное обновление
- Тихое обновление
Условия корректной работы SDK
Для работы RuStore In-app updates SDK необходимо соблюдение следующих условий.
- Kotlin
- Java
- Приложение загружено в Консоль RuStore.
- Приложение прошло модерацию (публиковать приложение необязательно).
- Подпись тестируемой сборки (например,
debug
) приложения должна совпадать с подписью сборки приложения, которая была загружена в консоль и прошла модерацию ранее (например,release
).
- ОС Android версии 7.0 или выше.
- Версия RuStore на устройстве пользователя актуальная.
- Пользователь авторизован в RuStore.
- Приложению RuStore разрешена установка приложений.
- Приложение загружено в Консоль RuStore.
- Приложение прошло модерацию (публиковать приложение необязательно).
- Подпись тестируемой сборки (например,
debug
) приложения должна совпадать с подписью сборки приложения, которая была загружена в консоль и прошла модерацию ранее (например,release
).
- ОС Android версии 7.0 или выше.
- Версия RuStore на устройстве пользователя актуальная.
- Пользователь авторизован в RuStore.
- Приложению RuStore разрешена установка приложений.
Подключение в проект
- Kotlin
- Java
Подключите репозиторий, как показано в примере ниже.
repositories {
maven {
url = uri("https://artifactory-external.vkpartner.ru/artifactory/maven")
}
}
- Подключение BOM
- Подключение версии напрямую
Подлюключение bom-файла позволяет вам иметь одну версию нескольких RuStore SDK
Преимущества использования BOM-файла для конфигурации.
-
Единое управление версиями:
- С BOM вы можете управлять версиями всех зависимостей из одного файла. Это особенно полезно, если вы используете несколько библиотек, которые должны быть совместимы друг с другом.
- Например, если у вас есть несколько библиотек от RuStore, таких как
ru.rustore.sdk:billingclient
иru.rustore.sdk:pushclient
, вы можете использовать BOM, чтобы гарантировать, что все они будут совместимы друг с другом.
-
Упрощение обновлений:
- Обновление зависимостей становится проще, так как вам нужно изменить версию только в одном месте — в BOM-файле. Это снижает риск пропустить обновление какой-либо зависимости и избежать конфликтов версий.
- Например, если новая версия BOM-файла содержит обновленные версии всех библиотек, вам достаточно обновит ь только BOM-файл, а не каждую зависимость по отдельности.
-
Повышение совместимости:
- Использование BOM помогает избежать конфликтов версий между различными библиотеками. Это особенно важно, когда библиотеки имеют зависимости друг от друга.
- Например, если две библиотеки зависят от разных версий одной и той же библиотеки, это может вызвать конфликты. BOM помогает избежать таких ситуаций, гарантируя, что все зависимости совместимы.
dependencies {
implementation(platform("ru.rustore.sdk:bom:7.0.0"))
implementation("ru.rustore.sdk:appupdate")
}
dependencies {
implementation("ru.rustore.sdk:appupdate:7.0.0")
}
Подключите репозиторий, как показано в примере ниже.
repositories {
maven {
url "https://artifactory-external.vkpartner.ru/artifactory/maven"
}
}
- Подключение BOM
- Подключение версии напрямую
Преимущества использования BOM-файла для конфигурации.
-
Единое управление версиями:
- С BOM вы можете управлять версиями всех зависимостей из одного файл а. Это особенно полезно, если вы используете несколько библиотек, которые должны быть совместимы друг с другом.
- Например, если у вас есть несколько библиотек от RuStore, таких как
ru.rustore.sdk:billingclient
иru.rustore.sdk:pushclient
, вы можете использовать BOM, чтобы гарантировать, что все они будут совместимы друг с другом.
-
Упрощение обновлений:
- Обновление зависимостей становится проще, так как вам нужно изменить версию только в одном месте — в BOM-файле. Это снижает риск пропустить обновление какой-либо зависимости и избежать конфликтов версий.
- Например, если новая версия BOM-файла содержит обновленные версии всех библиотек, вам достаточно обновить только BOM-файл, а не каждую зависимость по отдельности.
-
Повышение совместимости:
- Использование BOM помогает избежать конфликтов версий между различными библиотеками. Это особенно важно, когда библиотеки имеют зависимости друг от друга.
- Например, если две библиотеки зависят от разных версий одной и той же библиотеки, это может вызвать конфликты. BOM помогает избежать таких ситуаций, гарантируя, что все зависимости сов местимы.
dependencies {
implementation platform("ru.rustore.sdk:bom:7.0.0")
implementation "ru.rustore.sdk:appupdate"
}
dependencies {
implementation "ru.rustore.sdk:appupdate:7.0.0"
}
Создание менеджера обновлений
- Kotlin
- Java
Перед вызовом методов библиотеки необходимо создать менеджер обновлений.
val updateManager = RuStoreAppUpdateManagerFactory.create(context)
Перед вызовом методов библиотеки необходимо создать менеджер обновлений.
RuStoreAppUpdateManager ruStoreAppUpdateManager = RuStoreAppUpdateManagerFactory.INSTANCE.create(context);
Проверка наличия обновлений
- Kotlin
- Java
getAppUpdateInfo()
. При вызове данного метода проверяются следующие условия.
- На устройстве пользователя установлена актуальная версия RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Приложению RuStore разрешена установка приложений.
- Пользователь авторизован в RuStore.
AppUpdateInfo
, который будет содержать в себе информацию о необходимости обновления. Запросите этот объект заранее и закэшируйте его, чтобы запросить у пользователя запуск скачивания обновления без задержки и в удобный для пользователя момент времени.
ruStoreAppUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability == UpdateAvailability.UPDATE_AVAILABLE) {
// Обновление доступно(здесь можно зарегистрировать listener и начать загрузку)
}
}
.addOnFailureListener { throwable ->
Log.e(TAG, "getAppUpdateInfo error", throwable)
}
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)
— в ожидании.
Запуск скачивания обновления возможен только в том случае, если поле updateAvailability
содержит значение UPDATE_AVAILABLE
.
getAppUpdateInfo()
. При вызове данного метода проверяются следующие условия.
- На устройстве пользователя установлена актуальная версия RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Приложению RuStore разрешена установка приложений.
- Пользователь авторизован в RuStore.
AppUpdateInfo
, который будет содержать в себе информацию о необходимости обновления. Запросите этот объект заранее и закэшируйте его, чтобы запросить у пользователя запуск скачивания обновления без задержки и в удобный для пользователя момент времени.
ruStoreAppUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.getUpdateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
// Обновление доступно(здесь можно зарегистрировать listener и начать загрузку)
}
})
.addOnFailureListener(throwable ->
Log.e(TAG, "getAppUpdateInfo error", throwable)
);
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)
— в ожидании.
Запуск скачивания обновления возможен только в том случае, если поле updateAvailability
содержит значение UPDATE_AVAILABLE
.
Скачивание и установка обновлений
Использование слушателя
После подтверждения доступности обновления (AppUpdateInfo
) вы можете запросить статус скачивания обновления — для этого запустите слушатель статуса скачивания обновления.
Проверка статуса скачивания обновления
- Kotlin
- Java
Используйте метод 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")
}
}
}
Объект state
описывает текущий статус скачивания. Ниже представлено содержимое объекта.
-
installStatus
— статус установки обновления, если пользователь уже устанавливает обновление в текущий момент времени:UNKNOWN (int == 0)
— по умолчанию;DOWNLOADED (int == 1)
— скачано;DOWNLOADING (int == 2)
— скачивается;FAILED (int == 3)
— ошибка;PENDING (int == 5)
— в ожидании;
В SDK обновлений нет особого статуса для ситуации, когда пользователь отменил скачивание обновления. Если пользователь прервал обновление на этапе скачивания, installStatus
возвращает исходный статус UNKNOWN
(0
) с кнопкой Скачать.
Если пользователь уже скачал обновление, но отменил установку, то installStatus
вернёт значение DOWNLOADED
(1
).
Рассмотрим следующие варианты.
- Пользователь начал скачивание обновления, но отменил скачивание — в этом случае:
updateAvailability
—UPDATE_AVAILABLE
(2
);installStatus
—UNKNOWN
(0
).
- Пользователь скачал файл обновления, но не стал его устанавливать — в этом случае:
updateAvailability
—UPDATE_AVAILABLE
(2
);installStatus
—DOWNLOADED
(1
).
bytesDownloaded
— количество загруженных байт;totalBytesToDownload
— общее количество байт, которое необходимо скачать;installErrorCode
— код ошибки во время скачивания. Коды ошибок описаны в разделе Обработка ошибок.
Используйте метод registerListener()
.
ruStoreAppUpdateManager.registerListener(state -> {
switch (state.getInstallStatus()) {
case InstallStatus.DOWNLOADED:
// Обновление готово к установке
break;
case InstallStatus.DOWNLOADING:
long totalBytes = installState.getTotalBytesToDownload();
long bytesDownloaded = installState.getBytesDownloaded();
// Здесь можно отобразить прогресс скачивания
break;
case InstallStatus.FAILED:
Log.e(TAG, "Downloading error");
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
).
Рассмотрим следующие варианты.
- Пользователь начал скачивание обновления, но отменил скачивание — в этом случае:
updateAvailability
—UPDATE_AVAILABLE
(2
);installStatus
—UNKNOWN
(0
).
- Пользователь скачал файл обновления, но не стал его устанавливать — в этом случае:
updateAvailability
—UPDATE_AVAILABLE
(2
);installStatus
—DOWNLOADED
(1
).
bytesDownloaded
— количество загруженных байт;totalBytesToDownload
— общее количество байт, которое необходимо скачать;installErrorCode
— код ошибки во время скачивания. Коды ошибок описаны в разделе Обработка ошибок.
Удаление слушателя
- Kotlin
- Java
Если необходимости в слушателе больше нет, воспользуйтесь методом удаления слушателя unregisterListener()
, передав в метод ранее зарегистрированный слушатель.
ruStoreAppUpdateManager.unregisterListener(listener)
Если необходимости в слушателе больше нет, воспользуйтесь методом удаления слушателя unregisterListener()
, передав в метод ранее зарегистрированный слушатель.
ruStoreAppUpdateManager.unregisterListener(listener);
Запуск скачивания обновления
Отложенное обновление
- Kotlin
- Java
Запуск сценария обновления
Для запуска скачивания обновления приложения вызовите метод startUpdateFlow()
.
Объект AppUpdateInfo
после однократного использования становится невалидным. Для повторного вызова метода startUpdateFlow()
запросите AppUpdateInfo
, снова используя метод getAppUpdateInfo()
.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().build())
.addOnSuccessListener { resultCode ->
if (resultCode == Activity.RESULT_CANCELED) {
// Пользователь отказался от скачивания
}
}
.addOnFailureListener { throwable ->
Log.e(TAG, "startUpdateFlow error", throwable)
}
Если пользователь подтвердил скачивание обновления, тогда resultCode = Activity.RESULT_OK
, если отказался, то resultCode = Activity.RESULT_CANCEL
.
После получения статуса DOWNLOADED
вы можете вызвать метод установки обновления completeUpdate().
Рекомендуется уведомить пользователя о готовности обновления к установке.
Метод может вернуть ошибку.
Запуск сценария обновления
Для запуска скачивания обновления приложения вызовите метод startUpdateFlow()
.
Объект AppUpdateInfo
после однократного использования становится невалидным. Для повторного вызова метода startUpdateFlow()
запросите AppUpdateInfo
, снова используя метод getAppUpdateInfo()
.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, new AppUpdateOptions.Builder().build())
.addOnSuccessListener(resultCode -> {
if (resultCode == Activity.RESULT_CANCELED) {
// Пользователь отказался от скачивания
}
})
.addOnFailureListener(throwable ->
Log.e(TAG, "startUpdateFlow error", throwable)
);
Если пользователь подтвердил скачивание обновления, тогда resultCode = Activity.RESULT_OK
, если отказался, то resultCode = Activity.RESULT_CANCEL
.
После получения статуса DOWNLOADED
вы можете вызвать метод установки обновления completeUpdate().
Рекомендуется уведомить пользователя о готовности обновления к установке.
Метод может вернуть ошибку.
Принудительное обновление
- Kotlin
- Java
Запуск сценария обновления
После получения AppUpdateInfo
вы можете проверить доступность принудительного обновления.
if (appUpdateInfo.isUpdateTypeAllowed(IMMEDIATE)) {
// Принудительное обновление доступно
}
Результат функции isUpdateTypeAllowed
рекомендуется использовать для принятия решения о запуске принудительного обновления, но данный результат не влияет на возможность запуска сценария. Необходимость запуска сценария обновления может происходить по вашей внутренней логике.
Для запуска сценария обновления используйте метод startUpdateFlow()
.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().appUpdateType(IMMEDIATE).build())
.addOnSuccessListener { resultCode ->
}
.addOnFailureListener { throwable ->
}
resultCode (Int)
:
Activity.RESULT_OK (-1)
— обновление выполнено, код может не быть получен, т. к. приложение в момент обновления завершается.Activity.RESULT_CANCELED (0)
— флоу прервано пользователем, или произошла ошибка. Предполагается, что при получении этого кода следует завершить работу приложения.ActivityResult.ACTIVITY_NOT_FOUND (2)
— RuStore не установлен, либо установл ена версия, которая не поддерживает принудительное обновление (RuStore versionCode
<191
).
throwable
— ошибка старта сценария обновления.
При успешном обновлении дальнейших действий не требуется.
Запуск сценария обновления
После получения AppUpdateInfo
вы можете проверить доступность принудительного обновления.
if (appUpdateInfo.isUpdateTypeAllowed(IMMEDIATE)) {
// Принудительное обновление доступно
}
Результат функции isUpdateTypeAllowed
рекомендуется использовать для принятия решения о запуске принудительного обновления, но данный результат не влияет на возможность запуска сценария. Необходимость запуска сценария обновления может происходить по вашей внутренней логике.
Для запуска сценария обновления используйте метод startUpdateFlow()
.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, new AppUpdateOptions.Builder().appUpdateType(AppUpdateType.IMMEDIATE).build()
.addOnSuccessListener(resultCode ->
)
.addOnFailureListener(throwable ->
);
resultCode (Int)
:
Activity.RESULT_OK (-1)
— обновление выполнено, код может не быть получен, т. к. приложение в момент обновления завершается.Activity.RESULT_CANCELED (0)
— флоу прервано пользователем, или произошла ошибка. Предполагается, что при получении этого кода следует завершить работу приложения.ActivityResult.ACTIVITY_NOT_FOUND (2)
— RuStore не установлен, либо установлена версия, которая не поддерживает принудительное обновление (RuStore versionCode
<191
).
throwable
— ошибка старта сценария обновления.
При успешном обновлении дальнейших действий не требуется.
Тихое обновление
- Kotlin
- Java
Запуск сценария обновления
Для запуска скачивания обновления приложения необходимо вызвать метод startUpdateFlow()
с аргументом AppUpdateInfo
, полученный в методе getAppUpdateInfo()
, и установить тип обновления в AppUpdateOptions
в значение SILENT
.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().appUpdateType(SILENT).build())
.addOnSuccessListener { resultCode ->
}
.addOnFailureListener { throwable ->
}
При вызове onSuccessListener
с resultCode = Activity.RESULT_OK
будет зарегистрирована задача на скачивание обновления.
В данном сценарии может быть вызван только onSuccessListener
с resultCode = Activity.RESULT_OK
, либо onFailureListener
.
После вызова метода вы можете следить за статусом скачивания обновления в слушателе.
После получения статуса DOWNLOADED
вы можете вызвать метод установки обновления completeUpdate(). Рекомендуется уведомить пользователя о готовности обновления к установке.
Для тихого обновления рекомендуется реализовать свой интерфейс.
Запуск сценария обновления
Для запуска скачивания обновления приложения необходимо вызвать метод startUpdateFlow()
с аргументом AppUpdateInfo
, полученный в методе getAppUpdateInfo()
, и установить тип обновления в AppUpdateOptions
в значение SILENT
.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, new AppUpdateOptions.Builder().appUpdateType(AppUpdateType.SILENT).build())
.addOnSuccessListener(resultCode ->
)
.addOnFailureListener(throwable ->
);
При вызове onSuccessListener
с resultCode = Activity.RESULT_OK
будет зарегистрирована задача на скачивание обновления.
В данном сценарии может быть вызван только onSuccessListener
с resultCode = Activity.RESULT_OK
, либо onFailureListener
.
После вызова метода вы можете следить за статусом скачивания обновления в слушателе.
После получения статуса DOWNLOADED
вы можете вызвать метод установки обновления completeUpdate(). Рекомендуется уведомить пользователя о готовности обновления к установке.
Для тихого обновления рекомендуется реализовать свой интерфейс.
Установка обновления
- Kotlin
- Java
Для запуска установки обновления вызовите метод completeUpdate()
.
Для запуска установки обновления вызовите метод completeUpdate(appUpdateOptions: AppUpdateOptions)
.
В метод можно передавать только 2 типа завершения установки FLEXIBLE
и SILENT
, отложенное и тихое обновление соответственно.
var type: Int = AppUpdateType.FLEXIBLE
ruStoreAppUpdateManager
.completeUpdate(AppUpdateOptions.Builder().appUpdateType(type).build())
.addOnFailureListener { throwable ->
Log.e(TAG, "update error", throwable)
}
type
- тип обновления AppUpdateType
.
Если передать тип обновлений FLEXIBLE
, то приложение перезапустится. Пример флоу пользователя ниже.
Если передать тип обновлений SILENT
, то приложение закроется без перезапуска. Пример флоу пользователя ниже.
Обновление без UI от RuStore:
- UI-диалог завершения обновления не будет показан.
- В случае успешного обновления приложение будет закрыто.
Для запуска установки обновления вызовите метод completeUpdate()
.
Для запуска установки обновления вызовите метод completeUpdate(appUpdateOptions: AppUpdateOptions)
.
В метод можно передавать только 2 типа завершения установки FLEXIBLE
и SILENT
, отложенное и тихое обновление соответственно.
int type = AppUpdateType.FLEXIBLE;
ruStoreAppUpdateManager
.completeUpdate(new AppUpdateOptions.Builder().appUpdateType(AppUpdateType.FLEXIBLE).build())
.addOnFailureListener(throwable ->
Log.d(TAG, "Throwable: " + throwable);
);
type
- тип обновления AppUpdateType
.
Если передать тип обновлений FLEXIBLE
, то приложение перезапустится. :
Если передать тип обновлений SILENT
, то приложение закроется без перезапуска. Пример флоу пользователя ниже.
Обновление без UI от RuStore:
- UI-диалог завершения обновления не будет показан.
- В случае успешного обновления приложение будет закрыто.
Обработка ошибок
Если вы получили в ответ onFailure
, не рекомендуется самостоятельно отображать ошибку пользователю. Отображение ошибки может негативно повлиять на пользовательский опыт.
Возможные ошибки
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)
— неизвестная ошибка отрытия активити.