Accelerated Android App Updates with In-App Update API
Forced update for Android is a Google Play tool that delivers patches without user action. Users don't update themselves. According to Play Console data, the average installation time is about 3 weeks. A critical fix waits for the user 21 days. This API solves the problem directly. Forced update via Immediate mode reduces the share of outdated versions to 5% within 48 hours. Our team has accumulated 7+ years of experience integrating Android update mechanisms. We've implemented this tool in 40+ projects. The cost of basic integration starts after analysis. Full cycle with testing and CI/CD is quoted individually. Contact us for an audit: we'll reduce the delivery time of critical patches to minutes.
Which In-App Update mode to choose?
Google Play In-App Update API, available via com.google.android.play:app-update-ktx, provides two scenarios. Minimum Android SDK is level 21. The library weighs about 150 KB and works on Android 5.0 and higher.
Flexible update — background download, user continues working. Ideal for feature releases. After download completion, a snackbar appears with a "Restart" button. If the user dismisses it, you need to separately track InstallStatus.DOWNLOADED and show a repeat request.
Immediate update — full-screen blocking interface from Google Play. The app is unavailable until the update completes. Used for critical patches: encryption schema change, mandatory database migration, deprecation of old backend API. Immediate update is faster than normal waiting: installation takes 2-5 minutes, not 3 weeks. Savings on supporting outdated versions reach 70%. According to Google I/O data, install rate in Immediate scenario is 60-80% higher.
| Characteristic | Flexible | Immediate |
|---|---|---|
| App blocking | No | Yes |
| Suitable for | Feature releases | Critical patches |
| Time to update | 3-7 days | Instant |
| Risk level | Low | Medium (possible refusal) |
What causes problems in implementation?
The most common mistake is initializing AppUpdateManager without checking update availability. The method appUpdateManager.appUpdateInfo returns Task<AppUpdateInfo>, and it must be awaited asynchronously. Attempts to call startUpdateFlowForResult without a ready AppUpdateInfo throw IllegalStateException at runtime.
The second frequent bug is missing the state when update is unavailable. This manifests on builds from Firebase App Distribution and when working with FakeAppUpdateManager. In production, this path is unreachable, but in CI tests fail.
The third problem is versioning. Comparison is done by versionCode, not versionName. If multiple flavors share the same versionCode, the update won't be offered. This rule applies even when the binaries are different.
Turnkey In-App Update implementation
Integration starts with auditing the current versioning scheme — we check that versionCode increases monotonically and there are no collisions between flavors. Then we add the dependency and write an UpdateManager class in the domain layer (clean architecture — UI doesn't know about Play Services directly).
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 ) } } For Immediate scenario, we add staleDays — forced update is enabled only if the update has been available for more than N days. Recommended threshold is 3 to 7 days for feature releases. This reduces user irritation with minor patches.
Handling onResume is critical. If the user minimized the app during Flexible download and comes back — we check installStatus and offer a restart. Without this, the app runs on old code even though the new one is already on disk.
Handling forced update cancellation
Immediate update doesn't mean the user will definitely update. They can close the app — onActivityResult returns RESULT_CANCELED. You need to correctly handle this branch: log the event and possibly show a dialog explaining the need to update. In some cases, you can switch to Flexible update if permissible. Get a consultation on In-App Update implementation, and we'll propose an individual solution for your app.
Testing In-App Update with FakeAppUpdateManager
FakeAppUpdateManager from play-app-update allows emulating all states without publishing to Play Store. In Espresso tests, you can run the full cycle: availability → download start → completion → restart. According to Google Play In-App Update API documentation, without this coverage, bugs go into production. Google Play shows UI on top of the app. Standard UI tests don't see it. The test cycle in CI takes 4-6 minutes.
| Stage | Action | Expected Result |
|---|---|---|
| Mock-test | Set updateAvailability=UPDATE_AVAILABLE |
Update flow starts |
| Refusal | Return RESULT_CANCELED |
App continues, refusal logged |
| Downloading | Emulate InstallStatus.DOWNLOADING |
Progress shown |
| Completion | InstallStatus.DOWNLOADED |
Restart prompt |
Common integration mistakes
- Ignoring asynchronicity of appUpdateInfo
- Missing handling of RESULT_CANCELED
- versionCode conflict between flavors
Work process and timelines
- Analytics — audit of versioning, architecture, and current dependencies (1 day).
-
Design — mode selection, determination of
staleDays, writing integration tests (1-2 days). -
Implementation —
UpdateManagercode,onResumehandling, logging (1-2 days). - Testing — unit, integration, UI automation (1 day).
- Deployment — publish to Internal Testing, verify on real devices (1 day).
Estimated time — from 2 to 5 working days depending on architecture complexity.
What is included in the work
- Audit of current versioning scheme
- Implementation of
UpdateManagerwith all state handling - Unit tests and UI tests with
FakeAppUpdateManager - Integration with CI/CD
- Operational documentation
- Support for 2 weeks after release
Contact us for an accurate estimate of your project — we'll provide a detailed plan and guarantee results.







