flutter_local_notifications
flutter_local_notifications copied to clipboard
Context.startForegroundService() did not then call Service.startForeground()
Describe the bug Except for this one time, my app, which uses this package, runs fine without this error. However I ran into this crash that occurred maybe 1/2 to 2 minutes after starting the app.
To Reproduce
- (Likely) use custom app settings to disable sticky notifications within app
- Launch the otherwise mostly / usually working app in Android SDK 35 x86 emulator
- Random crash after a short while
- Relaunch app, without changing anything obviously related to notifications
- No crash
Launching lib/main.dart on sdk gphone64 x86 64 in debug mode...
✓ Built build/app/outputs/flutter-apk/app-debug.apk
I/FlutterBootReceiverPlugin( 6099): onAttachedToEngine
I/FlutterBackgroundExecutor( 6099): Starting BootHandlerService...
I/FlutterBootReceiverPlugin( 6099): onAttachedToEngine
Connecting to VM Service at ws://127.0.0.1:32997/DfT0pFTfUK8=/ws
Connected to the VM Service.
W/BootHandlerService( 6099): Attempted to start a duplicate background isolate. Returning...
[log] App data directory: /data/user/0/com.example.app/files/
I/BootHandlerService( 6099): BootHandlerService started!
I/FlutterBackgroundExecutor( 6099): Executing Dart callback: -7767485495945997519...
[log] App data directory: /data/user/0/com.example.app/files/
D/ProfileInstaller( 6099): Installing profile for com.example.app
D/EGL_emulation( 6099): app_time_stats: avg=1836.44ms min=4.41ms max=16048.77ms count=9
D/EGL_emulation( 6099): app_time_stats: avg=14.18ms min=1.07ms max=30.62ms count=56
D/EGL_emulation( 6099): app_time_stats: avg=6.06ms min=2.34ms max=11.26ms count=60
D/AndroidRuntime( 6099): Shutting down VM
E/AndroidRuntime( 6099): FATAL EXCEPTION: main
E/AndroidRuntime( 6099): Process: com.example.app, PID: 6099
E/AndroidRuntime( 6099): android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{9e28a5e u0 com.example.app/com.dexterous.flutterlocalnotifications.ForegroundService c:com.example.app}
E/AndroidRuntime( 6099): at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException(ActivityThread.java:2271)
E/AndroidRuntime( 6099): at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:2239)
E/AndroidRuntime( 6099): at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException(Unknown Source:0)
E/AndroidRuntime( 6099): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2557)
E/AndroidRuntime( 6099): at android.os.Handler.dispatchMessage(Handler.java:107)
E/AndroidRuntime( 6099): at android.os.Looper.loopOnce(Looper.java:232)
E/AndroidRuntime( 6099): at android.os.Looper.loop(Looper.java:317)
E/AndroidRuntime( 6099): at android.app.ActivityThread.main(ActivityThread.java:8705)
E/AndroidRuntime( 6099): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 6099): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
E/AndroidRuntime( 6099): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
I/Process ( 6099): Sending signal. PID: 6099 SIG: 9
Lost connection to device.
Exited.
Expected behavior The expectation was for the app to not crash this one time.
Sample code to reproduce the problem
// run from background isolate
await notifier.initializeAlertNotifications();
await notifier.startAnroidStickyNotification();
// ...
Future<void> initializeAlertNotifications() async {
if (Platform.isLinux) {
var initializationSettingsLinux =
const LinuxInitializationSettings(defaultActionName: "Launch app");
var initializationSettings =
InitializationSettings(linux: initializationSettingsLinux);
await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
} else if (Platform.isAndroid) {
const AndroidNotificationChannel stickyChannel =
AndroidNotificationChannel(
stickyNotificationChannelId, stickyNotificationChannelName,
description: stickyNotificationChannelDescription,
importance: Importance.low);
const AndroidNotificationChannel alertChannel =
AndroidNotificationChannel(
alertsNotificationChannelId, alertsNotificationChannelName,
description: alertsNotificationChannelDescription,
importance: Importance.max);
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(stickyChannel);
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(alertChannel);
} else {
throw Exception("Unsupported platform for notifications.");
}
}
Future<void> startAnroidStickyNotification() async {
if (!Platform.isAndroid || !_settings.notificationsEnabled) {
return;
}
var activeAlerts = await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.getActiveNotifications();
if (activeAlerts
?.where((alert) => alert.id == stickyNotificationId)
.isNotEmpty ??
false) {
return;
}
var duration = Util.prettyPrintDuration(
duration: Duration(seconds: _settings.refreshInterval),
longForm: true,
stripLeadingOne: true);
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.startForegroundService(stickyNotificationId, stickyNotificationTitle,
"$stickyNotificationContentStart $duration",
notificationDetails: _stickyAndroidNotificationDetails,
foregroundServiceTypes: {
AndroidServiceForegroundType.foregroundServiceTypeDataSync
});
}
Similar to what I mentioned in https://github.com/MaikuB/flutter_local_notifications/issues/2407, since this is something you'd been able to reproduce and foreground service support was a community contribute, I'd say this would also be one resolved by you submitting a PR back
I think that this issue likely belongs here instead: https://github.com/AhsanSarwar45/flutter_boot_receiver/issues/10. The mention of com.dexterous.flutterlocalnotifications.ForegroundService is likely due to the fact that it's referenced in the AndroidManifest.xml file as a foreground service.