App Update Manager
A comprehensive Flutter package for managing app updates across Play Store, App Store, and custom backends with flexible update strategies.

A comprehensive Flutter package for managing app updates across Play Store, App Store, and custom backends with flexible update strategies, background checks, and beautiful UI.
Features#
✨ Multi-Platform Support
- ✅ Android (Play Store with in-app updates)
- ✅ iOS (App Store)
- ✅ Custom backend API
- ✅ Windows, macOS, Linux (custom updates)
🎯 Update Strategies
- Flexible Updates - User can dismiss and update later
- Immediate Updates - Blocks app usage until updated
- Optional Updates - Shows notification but allows continued use
🎨 Customizable UI
- Beautiful dialogs and bottom sheets
- Fully customizable colors, text, and icons
- Dark mode support
- Material 3 design
🚀 Advanced Features
- Background update checks with WorkManager
- Version caching to reduce API calls
- Release notes display
- File size information
- Force updates for critical versions
- Minimum supported version enforcement
- Regional rollouts support
- A/B testing capabilities
- Analytics integration
- Network connectivity handling (WiFi-only option)
Installation#
Add this to your pubspec.yaml:
dependencies:
app_update_manager: ^1.0.0Platform-Specific Setup#
Android#
Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />iOS#
Add to ios/Runner/Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>Quick Start#
Basic Usage#
import 'package:app_update_manager/app_update_manager.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize
await AppUpdateManager.initialize(
config: UpdateConfig(
playStoreId: 'com.yourapp.package',
appStoreId: '123456789',
customUpdateUrl: 'https://api.yourapp.com/version',
),
);
runApp(MyApp());
}
// Check for updates
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
await AppUpdateManager.checkAndShowUpdate(
context: context,
);
},
child: Text('Check for Updates'),
),
),
);
}
}Custom Backend API#
Your backend should return JSON in this format:
{
"latest_version": "1.2.0",
"current_version": "1.0.0",
"release_notes": "Bug fixes and improvements",
"download_url": "https://...",
"is_forced": false,
"is_critical": false,
"minimum_supported_version": "1.0.0",
"file_size_bytes": 25600000,
"release_date": "2024-01-15T10:30:00Z"
}Query parameters sent to your API:
platform- Operating system (android, ios, etc.)current_version- Current app versionbuild_number- Current build numberpackage_name- App package nameregion- Region code (if configured)test_group- A/B test group (if configured)
Custom UI#
await AppUpdateManager.checkAndShowUpdate(
context: context,
useBottomSheet: true,
uiConfig: UpdateUIConfig(
title: 'New Version Available! 🎉',
message: 'Update to get the latest features',
updateButtonText: 'Update Now',
laterButtonText: 'Maybe Later',
primaryColor: Colors.purple,
showReleaseNotes: true,
showFileSize: true,
customIcon: Icon(Icons.rocket_launch),
),
);Background Checks#
await AppUpdateManager.initialize(
config: UpdateConfig(
// ... other config
enableBackgroundCheck: true,
backgroundCheckInterval: 24, // hours
wifiOnly: true, // Only check on WiFi
),
);
// Check if background update was found
final hasUpdate = await AppUpdateManager.hasBackgroundUpdate();Force Updates#
await AppUpdateManager.initialize(
config: UpdateConfig(
// ... other config
strategy: UpdateStrategy.immediate, // Force immediate update
),
);Analytics Integration#
await AppUpdateManager.initialize(
config: UpdateConfig(
// ... other config
enableAnalytics: true,
onAnalyticsEvent: (event, data) {
// Send to your analytics service
FirebaseAnalytics.instance.logEvent(
name: 'app_update_${event.name}',
parameters: data,
);
},
),
);Configuration Options#
UpdateConfig#
| Parameter | Type | Description | Default |
|---|---|---|---|
playStoreId | String? | Android package name | null |
appStoreId | String? | iOS app ID | null |
customUpdateUrl | String? | Custom API endpoint | null |
customHeaders | Map<String, String>? | HTTP headers for API | null |
strategy | UpdateStrategy | Update strategy | flexible |
backgroundCheckInterval | int | Hours between checks | 24 |
enableBackgroundCheck | bool | Enable background checking | false |
showDialogAutomatically | bool | Auto-show dialog | true |
enableCaching | bool | Cache version info | true |
cacheDuration | int | Cache duration (hours) | 6 |
requestTimeout | int | API timeout (seconds) | 30 |
wifiOnly | bool | Check only on WiFi | false |
regionCode | String? | Region for rollouts | null |
testGroup | String? | A/B test group | null |
enableAnalytics | bool | Enable analytics | false |
UpdateUIConfig#
| Parameter | Type | Description |
|---|---|---|
title | String? | Dialog title |
message | String? | Dialog message |
updateButtonText | String? | Update button text |
cancelButtonText | String? | Cancel button text |
laterButtonText | String? | Later button text |
backgroundColor | Color? | Background color |
primaryColor | Color? | Primary color |
titleStyle | TextStyle? | Title text style |
messageStyle | TextStyle? | Message text style |
showReleaseNotes | bool | Show release notes |
showFileSize | bool | Show file size |
customIcon | Widget? | Custom icon widget |
API Reference#
AppUpdateManager#
// Initialize the manager
static Future<void> initialize({required UpdateConfig config})
// Check for updates
static Future<UpdateInfo?> checkForUpdate()
// Check and show update dialog
static Future<bool> checkAndShowUpdate({
required BuildContext context,
UpdateUIConfig? uiConfig,
bool useBottomSheet = false,
})
// Get current version
static Future<String> getCurrentVersion()
// Clear cache
static Future<void> clearCache()
// Cancel background checks
static Future<void> cancelBackgroundChecks()
// Check for background update
static Future<bool> hasBackgroundUpdate()Examples#
Check the /example folder for complete examples:
basic_usage_example.dart- Simple implementationcustom_backend_example.dart- Custom API integrationadvanced_usage_example.dart- All features showcase
Testing#
// For testing, you can mock update scenarios
final testUpdateInfo = UpdateInfo(
latestVersion: AppVersion.parse('2.0.0'),
currentVersion: AppVersion.parse('1.0.0'),
releaseNotes: 'Test update',
isForced: false,
);
await showUpdateDialog(
context: context,
updateInfo: testUpdateInfo,
);Troubleshooting#
Android in-app update not working:
- Ensure your app is published on Play Store (internal testing track works)
- The update must be available on Play Store
- Test on a real device, not emulator
iOS App Store link not opening:
- Verify your App Store ID is correct
- Ensure
url_launchercan open App Store URLs
Background checks not working:
- Verify
workmanageris properly initialized - Check Android battery optimization settings
- iOS has strict background execution limits
Contributing#
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
License#
This project is licensed under the MIT License - see the LICENSE file for details.
Support#
For issues, feature requests, or questions:
- Open an issue on GitHub
Changelog#
See CHANGELOG.md for version history.
Related Projects

App Permissions
Centralized permission management system with automatic requests, status tracking, rationale dialogs, and graceful degradation.

App Storage
A simple and secure local storage package with support for primitives, collections, and JSON serialization.

Promo Carousel
A flexible, customizable promotional carousel package for Flutter