Прискорене оновлення Android-додатка з In-App Update API
Примусове оновлення для Android — інструмент Google Play, що дозволяє доставляти патчі без дій користувача. Користувачі не оновлюються самостійно. За даними Play Console, середній час встановлення — близько 3 тижнів. Критичний фікс чекає користувача 21 день. Цей API вирішує проблему напряму. Примусове оновлення через Immediate-режим знижує частку застарілих версій до 5% вже за 48 годин. Наша команда накопичила 7+ років досвіду в інтеграції Android-механізмів оновлень. Ми реалізували даний інструмент у 40+ проектах. Зв'яжіться з нами для аудиту: скоротимо час доставки критичних патчів до кількох хвилин.
Який режим In-App Update обрати?
Google Play In-App Update API, доступний через com.google.android.play:app-update-ktx, надає два сценарії. Мінімальний Android SDK — рівень 21. Бібліотека важить близько 150 КБ і працює на Android 5.0 і вище.
Flexible update — фонове завантаження, користувач продовжує роботу. Ідеально для фічевих релізів. Після завершення завантаження показується снекбар з кнопкою «Перезапустити». Якщо користувач його закрив — потрібно окремо відстежувати InstallStatus.DOWNLOADED і показувати повторний запит.
Immediate update — повноекранний блокуючий інтерфейс від Google Play. Додаток недоступний до завершення оновлення. Використовуємо при критичних патчах: зміна схеми шифрування, обов'язкова міграція БД, припинення підтримки старого API бекенду. Immediate update швидший за звичайне очікування: встановлення займає 2-5 хвилин, а не 3 тижні. Економія на підтримці застарілих версій сягає 70%. За даними Google I/O, install rate в Immediate-сценарії вищий на 60-80%.
| Характеристика | Flexible | Immediate |
|---|---|---|
| Блокування додатка | Ні | Так |
| Підходить для | Фічеві релізи | Критичні патчі |
| Час до оновлення | 3-7 днів | Миттєво |
| Рівень ризику | Низький | Середній (можлива відмова) |
Що викликає проблеми в реалізації?
Найчастіша помилка — ініціалізувати AppUpdateManager без перевірки доступності оновлення. Метод appUpdateManager.appUpdateInfo повертає Task<AppUpdateInfo>, і його потрібно чекати асинхронно. Спроби викликати startUpdateFlowForResult без готового AppUpdateInfo дають IllegalStateException в рантаймі.
Друга часта бага — пропуск стану, коли оновлення недоступне. Це проявляється на збірках з Firebase App Distribution і при роботі з FakeAppUpdateManager. В продакшені цей шлях недосяжний, але в CI падають тести.
Третя проблема — версіонування. Порівняння йде за versionCode, не за versionName. Якщо кілька флейворів ділять один versionCode, оновлення не запропонується. Це правило діє навіть коли бінарники різні.
Реалізація In-App Update під ключ
Інтеграція починається з аудиту поточної схеми версіонування — перевіряємо, що versionCode монотонно зростає і немає колізій між флейворами. Потім додаємо залежність і пишемо UpdateManager-клас у шарі domain (чиста архітектура — UI не знає про Play Services напряму).
val appUpdateManager = AppUpdateManagerFactory.create(context) val appUpdateInfoTask = appUpdateManager.appUpdateInfo appUpdateInfoTask.addOnSuccessListener { info -> if (info.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && info.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE) ) { appUpdateManager.startUpdateFlowForResult( info, AppUpdateType.FLEXIBLE, activity, REQUEST_CODE_UPDATE ) } } Для Immediate-сценарію додаємо staleDays — примусовий апдейт вмикається тільки якщо оновлення доступне більше N днів. Рекомендований поріг — від 3 до 7 днів для фічевих релізів. Це знижує роздратування користувачів при дрібних патчах.
Обробка onResume критична. Якщо користувач згорнув додаток під час Flexible-завантаження і повернувся — перевіряємо installStatus і пропонуємо рестарт. Без цього додаток працює на старому коді, хоча новий вже лежить на диску.
Обробка скасування примусового оновлення
Immediate update не означає, що користувач точно оновиться. Він може закрити додаток — onActivityResult поверне RESULT_CANCELED. Потрібно коректно обробляти цю гілку: логувати подію і, можливо, показувати діалог з поясненням необхідності оновлення. У деяких випадках можна перемкнутися на Flexible update, якщо це допустимо. Отримайте консультацію з впровадження In-App Update, і ми запропонуємо індивідуальне рішення для вашого додатка.
Тестування In-App Update з FakeAppUpdateManager
FakeAppUpdateManager з play-app-update дозволяє емулювати всі стани без публікації в Play Store. У Espresso-тестах можна прогнати повний цикл: доступність → початок завантаження → завершення → рестарт. Згідно з документацією Google Play In-App Update API, без цього покриття баги йдуть у продакшен. Google Play показує UI поверх додатка. Стандартні UI-тести його не бачать. Тестовий цикл у CI займає 4-6 хвилин.
| Етап | Дія | Очікуваний результат |
|---|---|---|
| Mock-тест | Встановити updateAvailability=UPDATE_AVAILABLE |
Запускається flow оновлення |
| Відмова | Повертаємо RESULT_CANCELED |
Додаток працює, логується відмова |
| Завантаження | Емулювати InstallStatus.DOWNLOADING |
Відображається прогрес |
| Завершення | InstallStatus.DOWNLOADED |
Пропозиція перезапуску |
Типові помилки при інтеграції
- Ігнорування асинхронності appUpdateInfo
- Відсутність обробки RESULT_CANCELED
- Конфлікт versionCode між флейворами
Процес роботи та терміни
- Аналітика — аудит версіонування, архітектури та поточних залежностей (1 день).
-
Проектування — вибір режимів, визначення
staleDays, написання інтеграційних тестів (1-2 дні). -
Реалізація — код
UpdateManager, обробкаonResume, логування (1-2 дні). - Тестування — unit, integration, UI автоматизація (1 день).
- Деплой — публікація в Internal Testing, перевірка на реальних пристроях (1 день).
Орієнтовний термін — від 2 до 5 робочих днів залежно від складності архітектури.
Що входить у роботу
- Аудит поточної схеми версіонування
- Реалізація
UpdateManagerз обробкою всіх станів - Юніт-тести та UI-тести з
FakeAppUpdateManager - Інтеграція з CI/CD
- Документація з експлуатації
- Підтримка протягом 2 тижнів після релізу
Зв'яжіться з нами для точної оцінки вашого проекту — ми надамо детальний план і гарантуємо результат.







