auto_start_flutter
A Flutter plugin to help manage background execution on Android, iOS, macOS, Windows, and Linux. It opens the OEM "Auto-Start" settings on Android, checks "Background App Refresh" on iOS, manages "Startup Apps / Login Items" on Windows and macOS, and can run Dart callbacks headlessly on boot, on a schedule, or on demand.
Features
- Auto-Start settings: manufacturer-specific "Auto-Start" / "App Launch" pages on Android (Xiaomi, Redmi, Poco, Oppo, Realme, Vivo, Huawei, Honor, Samsung, ASUS, OnePlus, Nokia, LeTV, Meizu, HTC, Infinix and more), Background App Refresh on iOS, Startup Apps on Windows, Login Items on macOS.
- Battery optimization: check the exemption status and open the system settings (Android), power settings (Windows/macOS).
- Exact alarms (Android 12+): check and request the permission.
- Boot callback: run a headless Dart callback when the device starts.
- Scheduled tasks: run a headless callback at an exact time; cancel and list tasks; Android tasks survive reboots.
- Headless execution: run a callback immediately without a UI.
- Foreground service keep-alive (Android).
- Status snapshot:
AutoStart.getStatus()collects everything above in one call. - No surprise permissions: the plugin declares no Android permissions. You add only those for the features you use (see Android Permissions).
Getting Started
dependencies:
auto_start_flutter: ^1.6.0
import 'package:auto_start_flutter/auto_start_flutter.dart';
Android build requirements
The plugin builds with Android Gradle Plugin 8.11.1, Kotlin 2.2.20 and JDK 17. Your app should use Gradle 8.14+ (matching Flutter's current minimums).
The AutoStart API
All methods are static and never throw: unsupported platforms and native errors are reported through the return value.
Methods that open a settings page return a SettingsResult:
| Value | Meaning |
|---|---|
opened |
The page was opened. |
notAvailable |
This device has no such page (e.g. no OEM auto-start manager). Fall back to AutoStart.openAppInfo(). |
unsupported |
The feature doesn't exist on this platform. |
failed |
The platform reported an error. |
AutoStart.scheduleTask returns a ScheduleResult: scheduled, exactAlarmDenied, invalidCallback, unsupported or failed.
Platform support
| Method | Android | iOS | Windows | macOS | Linux |
|---|---|---|---|---|---|
isAutoStartSettingsAvailable |
Manufacturer has an auto-start page | Background App Refresh available | true |
true |
true |
openAutoStartSettings |
Auto Start page | App Settings | Startup Apps | Login Items | No-op |
openAppInfo |
App Info | App Settings | Apps & Features | General Settings | No-op |
getManufacturer |
Build.MANUFACTURER |
"Apple" | "Microsoft" | "Apple" | "Linux" |
isBatteryOptimizationDisabled |
Doze exemption status | true |
true |
true |
true |
requestIgnoreBatteryOptimization |
Direct system dialog | App Settings | Power & Sleep | Energy Saver | No-op |
openBatteryOptimizationSettings |
Battery optimization list | App Settings | Power & Sleep | Energy Saver | No-op |
canScheduleExactAlarms |
AlarmManager check (Android 12+) |
true |
true |
true |
true |
openExactAlarmSettings |
"Alarms & reminders" (Android 12+) | not available | not available | not available | not available |
openCustomSetting |
Opens an activity | unsupported | unsupported | unsupported | unsupported |
registerBootCallback |
BOOT_COMPLETED + headless engine |
unsupported | Startup registry | SMAppService |
~/.config/autostart/ |
startForegroundService |
Foreground service | false |
false |
false |
false |
scheduleTask / cancelTask / getScheduledTaskIds |
AlarmManager (persisted across reboots) |
Local notification | Task Scheduler | Local notification | systemd user timers |
executeInBackground |
Headless engine | Headless engine | Background isolate | Background isolate | Background isolate |
completeBackgroundTask |
Releases the engine | Releases the engine | No-op | No-op | No-op |
Note: Standard Android APIs can't tell whether "Auto Start" is actually enabled.
isAutoStartSettingsAvailableonly reports that the device has such a page. Only iOS lets you verify the real background refresh status.
Usage
Auto-start settings
if (await AutoStart.isAutoStartSettingsAvailable()) {
final result = await AutoStart.openAutoStartSettings();
if (result == SettingsResult.notAvailable) {
await AutoStart.openAppInfo(); // generic fallback
}
}
Other helpers
String? manufacturer = await AutoStart.getManufacturer(); // "Xiaomi", "Apple", ...
// Android only: open a specific hidden settings activity you know about.
await AutoStart.openCustomSetting(
packageName: 'com.android.settings',
activityName: r'com.android.settings.Settings$PowerUsageSummaryActivity',
);
One-call status
final status = await AutoStart.getStatus();
// status.manufacturer, status.isAutoStartAvailable,
// status.isBatteryOptimizationDisabled, status.canScheduleExactAlarms
Boot callback
Runs a headless Dart callback (Android) or launches the app (desktop) when the device starts.
// Must be a top-level or static function.
@pragma('vm:entry-point')
Future<void> myBootCallback() async {
WidgetsFlutterBinding.ensureInitialized();
// ... do work ...
await AutoStart.completeBackgroundTask(); // release the headless engine
}
await AutoStart.registerBootCallback(myBootCallback);
Android needs the RECEIVE_BOOT_COMPLETED permission (see below).
Scheduled tasks
final result = await AutoStart.scheduleTask(
DateTime.now().add(const Duration(minutes: 5)),
myScheduledTaskCallback,
taskId: 'my_task_1', // optional; scheduling the same id again replaces the task
);
switch (result) {
case ScheduleResult.scheduled:
break;
case ScheduleResult.exactAlarmDenied:
await AutoStart.openExactAlarmSettings(); // Android 12+
default:
// invalidCallback / unsupported / failed
}
await AutoStart.cancelTask('my_task_1');
final pending = await AutoStart.getScheduledTaskIds();
- Android: uses
AlarmManagerand runs the callback headlessly even in Doze. Tasks are persisted and re-registered after a reboot; tasks that came due while the device was off run on boot. - iOS & macOS: Apple doesn't allow generic headless wakes at exact times, so a local notification is scheduled (the user is asked for notification permission on first use). When the user taps it, the app opens and
getLaunchArguments()containsscheduledTaskIdandcallbackHandle. - Windows: Windows Task Scheduler. Linux:
systemduser timers.
// On startup, check whether a scheduled task launched the app.
final args = await AutoStart.getLaunchArguments(); // iOS, macOS, Windows
if (args['scheduledTaskId'] == 'my_task_1') { ... }
Exact alarms (Android 12+)
if (!await AutoStart.canScheduleExactAlarms()) {
await AutoStart.openExactAlarmSettings(); // "Alarms & reminders" page
}
Headless execution
Runs a callback immediately, without a UI.
@pragma('vm:entry-point')
Future<void> myHeadlessTask() async {
WidgetsFlutterBinding.ensureInitialized();
// ... do work ...
await AutoStart.completeBackgroundTask();
}
await AutoStart.executeInBackground(myHeadlessTask);
- Android / iOS: a dedicated headless
FlutterEngine. CallAutoStart.completeBackgroundTask()at the end of the callback to destroy it immediately; otherwise Android destroys it after 5 minutes. - Desktop: a background Dart isolate. Plugins that support background isolates work; there is no UI.
Foreground service (Android)
Keeps the app alive with a persistent notification.
await AutoStart.startForegroundService(
title: 'Syncing data',
content: 'Do not close the app.',
);
await AutoStart.stopForegroundService();
Battery optimization
Android's Doze and App Standby restrict background work; Windows/macOS power settings can too.
final exempt = await AutoStart.isBatteryOptimizationDisabled() ?? false;
if (!exempt) {
// Recommended and Google Play safe: opens the system battery optimization list.
await AutoStart.openBatteryOptimizationSettings();
}
Direct dialog (ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS):
Warning
Google Play strictly limits which apps may request the direct exemption dialog. Only use requestIgnoreBatteryOptimization() if your app qualifies; otherwise use openBatteryOptimizationSettings().
await AutoStart.requestIgnoreBatteryOptimization();
Android Permissions
The plugin declares no permissions, so you only ship what you use. Add the ones for the features you enable to android/app/src/main/AndroidManifest.xml. Features whose permission is missing fail gracefully (a false / error result); they never crash the app.
| Feature | Permission(s) | Required? |
|---|---|---|
registerBootCallback, reboot-persistent scheduleTask |
RECEIVE_BOOT_COMPLETED |
Yes |
startForegroundService |
FOREGROUND_SERVICE; on Android 14+ also FOREGROUND_SERVICE_SPECIAL_USE; on Android 13+ POST_NOTIFICATIONS to show the notification |
Yes |
scheduleTask |
SCHEDULE_EXACT_ALARM, or USE_EXACT_ALARM (Android 13+, only for alarm/calendar apps per Google Play policy) |
Yes |
requestIgnoreBatteryOptimization |
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS |
Yes |
Headless callbacks (boot, scheduled, executeInBackground) |
WAKE_LOCK |
Optional: without it the callback still runs, but the device may go back to sleep before it finishes |
openBatteryOptimizationSettings, openAutoStartSettings, openAppInfo |
none | - |
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
Migrating from the top-level functions (1.6.0)
The original top-level functions still work but are @Deprecated. They keep their signatures and bool results and delegate to AutoStart.
| Deprecated | Replacement |
|---|---|
isAutoStartAvailable |
AutoStart.isAutoStartSettingsAvailable() |
getAutoStartPermission() |
AutoStart.openAutoStartSettings() → SettingsResult |
openAppInfo() |
AutoStart.openAppInfo() |
getDeviceManufacturer() |
AutoStart.getManufacturer() |
openCustomSetting(...) |
AutoStart.openCustomSetting(...) → SettingsResult |
isBatteryOptimizationDisabled |
AutoStart.isBatteryOptimizationDisabled() |
disableBatteryOptimization() |
AutoStart.requestIgnoreBatteryOptimization() |
openBatteryOptimizationSettings() |
AutoStart.openBatteryOptimizationSettings() |
canScheduleExactAlarms(), openExactAlarmSettings(), registerBootCallback, startForegroundService, stopForegroundService, executeInBackground, getLaunchArguments |
same names on AutoStart |
scheduleTask(...) → bool |
AutoStart.scheduleTask(...) → ScheduleResult |
New in 1.6.0 (only on AutoStart): cancelTask, getScheduledTaskIds, completeBackgroundTask, getStatus.
Testing
All calls go through AutoStartFlutterPlatform. In tests, extend it and assign AutoStartFlutterPlatform.instance to fake the plugin.
Contributing
If you find any issues or would like to add support for more devices, please file an issue or pull request on GitHub.