Skip to content

ForegroundServiceDidNotStartInTimeException on second startService() call — flutter_foreground_task 9.2.2 #382

@ovisopa

Description

@ovisopa

Hello everyone,

I'm building my first app ever, been a web developers in the past, for about 15 years but now I work in a different domain, so I do this in my free time.

A few months ago I started to build an iOS / Android Flutter app for outdoor gps recording, now a week ago one of my friends that started testing my app told me he uses the CLOSE ALL button in Android Recent Apps screen all the time, I told him the app can't record anymore if he closes it , but he show me another one that still records even after CLOSE ALL - a new badge is shown in that screen saying "1 active app" and from there you can force close even that service.

So this is how a week ago I started implementing flutter_foreground_task to my app, after many issue with all the ways my app works, I reached to this point where I fill I spin in circles, this seems to be the last issue affecting my app flow.

The first recording session works perfectly. After saving and immediately starting a second recording, the :recording process crashes with:

E/AndroidRuntime(12213): FATAL EXCEPTION: main
E/AndroidRuntime(12213): Process: com.trackthewild.app:recording, PID: 12213
E/AndroidRuntime(12213): android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
    Context.startForegroundService() did not then call Service.startForeground()

The :recording process dies immediately. The startForeground() deadline (5 seconds) is never met. No [TASK] log lines appear — onStartCommand either never runs or runs too late.

GPS recording runs in a separate Android process (:recording) using flutter_foreground_task. Both ForegroundService and GeolocatorLocationService are declared in that process.

AndroidManifest.xml:

<service
    android:name="com.pravera.flutter_foreground_task.service.ForegroundService"
    android:foregroundServiceType="location"
    android:process=":recording"
    android:stopWithTask="false"
    android:exported="false" />

<service
    android:name="com.baseflow.geolocator.GeolocatorLocationService"
    android:foregroundServiceType="location"
    android:process=":recording"
    android:exported="false" />

At the end of a recording session, the Dart task calls FlutterForegroundTask.stopService() followed immediately by exit(0):

// recording_task_handler.dart — _handleStop()
FlutterForegroundTask.skipServiceResponseCheck = true;
try { await FlutterForegroundTask.stopService(); } catch (_) {}
exit(0);

exit(0) is intentional: without it, the still-alive :recording process receives the next startForegroundService() intent but already has a running ForegroundService instance that cannot call startForeground() again — causing the same exception.

stopService() writes API_STOP to SharedPreferences. When Android's START_STICKY restarts the service after exit(0), onStartCommand reads API_STOP and calls stopForegroundService() immediately.

To start the service I use this:

// track_recording_service.dart — _startForegroundTask()
FlutterForegroundTask.skipServiceResponseCheck = true;
try {
  final result = await FlutterForegroundTask.startService(
    serviceId: 1001,
    notificationTitle: 'Recording Active',
    notificationText: 'App is recording your route',
    callback: startRecordingTask,
  );
  // ...
} finally {
  FlutterForegroundTask.skipServiceResponseCheck = false;
}

skipServiceResponseCheck = true is was added later to fix an issue on my sons Samsung device, to avoid ServiceTimeoutException (the Dart-side polling starves Android's main thread, so onStartCommand never fires).

I have a few questions if you did not spot already an issue in my code

1. Is calling exit(0) from inside the task Dart isolate the correct way to fully terminate the :recording process? Is there a safer alternative that guarantees the process is gone before the next startForegroundService() arrives?

  1. Does START_STICKY on a service declared with android:process=":recording" cause a ghost restart that can confuse Android's foreground service bookkeeping for the next startForegroundService() call?

  2. Is there a way to call startForeground() earlier in the service lifecycle (e.g. in onCreate()) to buy more time for the Flutter engine to initialize, without patching the plugin source?

  3. Has anyone successfully run two back-to-back recording sessions with this plugin on a separate process (android:process=":recording") without restarting the full JVM between them?

bellow a shorter Logcat around the crash:

I/flutter (11017): [Android] ForegroundTask start requested (watchdog will confirm)
E/AndroidRuntime(12213): FATAL EXCEPTION: main
E/AndroidRuntime(12213): Process: com.trackthewild.app:recording, PID: 12213
E/AndroidRuntime(12213): android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
    Context.startForegroundService() did not then call Service.startForeground():
    ServiceRecord{... com.trackthewild.app/com.pravera.flutter_foreground_task.service.ForegroundService ...}
D/FlutterGeolocator(11017): Geolocator foreground service disconnected
D/FlutterGeolocator(12341): Creating service.       ← geolocator retries in new PID
I/flutter (11017): [Android] task_live.json not fresh yet — retry in 2 s (4 left)
I/flutter (11017): [Android] task_live.json not fresh yet — retry in 2 s (3 left)
I/flutter (11017): [Android] task_live.json not fresh yet — retry in 2 s (2 left)
I/flutter (11017): [Android] task_live.json not fresh yet — retry in 2 s (1 left)
I/flutter (11017): [Android] Task watchdog: task_live.json stale after 20 s — GPS stream fallback
E/FlutterGeolocator(11017): Location background service has not started correctly

Any insight appreciated — especially from anyone who has implemented sequential recordings with flutter_foreground_task on a separate process.

Thank you in advance!

PS. This is the screenshot after my first recording session

Image

And this is after the second recording session

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions