foreground_background_manager

A production-ready Flutter plugin for:

  • 🔄 App lifecycle detection (foreground / background / paused / detached)
  • 🚀 Android Foreground Service — persists through minimize, background, AND app kill
  • ⏰ Background task scheduling (WorkManager on Android, BGTaskScheduler on iOS)
  • 🔔 Permissions handling (notifications, battery optimization)
  • 🔁 Auto-restart after app kill and device reboot

How "Always Running" Works

Three layers ensure the service survives every kill scenario:

Scenario Mechanism
App minimized / background Foreground service stays active (notification visible)
App killed by user (swipe) onTaskRemoved → AlarmManager restart + START_STICKY
OS kills service (memory) START_STICKY → OS auto-restarts with null intent
Device reboot FBMBootReceiver (BOOT_COMPLETED) → restarts service

Setup

Android AndroidManifest.xml

Add inside <manifest>:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

Add inside <application>:

<service
    android:name="com.example.foreground_background_manager.FBMForegroundService"
    android:exported="false"
    android:foregroundServiceType="dataSync"
    android:stopWithTask="false" />

<receiver
    android:name="com.example.foreground_background_manager.FBMBootReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>

iOS Info.plist

<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
    <string>processing</string>
</array>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
    <string>com.yourapp.sync_task</string>
</array>

Quick Start

// 1. Top-level callback dispatcher (MUST be top-level)
@pragma('vm:entry-point')
void callbackDispatcher() {
  ForegroundBackgroundManager.backgroundCallbackDispatcher();
}

// 2. Background task callback (MUST be top-level)
@pragma('vm:entry-point')
Future<void> mySync() async {
  print('Syncing in background...');
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await ForegroundBackgroundManager.initialize(
    callbackDispatcher: callbackDispatcher,
  );

  runApp(const MyApp());
}

Start a Kill-Proof Foreground Service

// Step 1: Request battery optimization ignore (IMPORTANT for OEMs)
await ForegroundBackgroundManager.permissions.requestIgnoreBatteryOptimization();

// Step 2: Request notification permission (Android 13+)
await ForegroundBackgroundManager.permissions.requestNotificationPermission();

// Step 3: Start service
await ForegroundBackgroundManager.startForegroundService(
  title: 'App Running',
  content: 'Service active — survives app kill',
  autoRestart: true, // ← this enables auto-restart
);

// Stop
await ForegroundBackgroundManager.stopForegroundService();

Lifecycle Streams

ForegroundBackgroundManager.lifecycleStream.listen((state) {
  print(state.label); // "Foreground (Resumed)", "Background (Paused)", etc.
});

ForegroundBackgroundManager.onForeground.listen((_) => print('→ Foreground'));
ForegroundBackgroundManager.onBackground.listen((_) => print('→ Background'));
ForegroundBackgroundManager.onAppKilled.listen((_) => print('→ Killed!'));

Background Tasks

await ForegroundBackgroundManager.registerBackgroundTask(
  taskId: 'sync_task',
  interval: const Duration(minutes: 15), // minimum on both platforms
  callback: mySync,
);

OEM-Specific Notes

OEM Action Required
Xiaomi / MIUI Enable "Autostart" in Security app. Battery optimization ignore is mandatory.
Huawei / EMUI Add app to "Protected apps". Battery optimization ignore required.
Samsung Disable "Put unused apps to sleep" for your app.
Stock Android Battery optimization ignore is usually sufficient.

Platform Limitations

iOS:

  • No foreground service — startForegroundService is a no-op.
  • BGTask execution is OS-controlled; minimum interval ~15 min; may be delayed.
  • Force-quit by user cancels all pending BGTasks.

Android:

  • WorkManager minimum repeat interval: 15 minutes.
  • SCHEDULE_EXACT_ALARM may need user grant on Android 12+.
  • On Android 14+, foregroundServiceType must be declared.