registerHeadlessTask static method
Registers a function to receive events from BackgroundGeolocation
while in the terminated ("Headless") state.
Note: Requires Config.enableHeadless:true. See the Android Headless Mode Guide.
In main.dart
, create a global function beside void main() {}
(Must be defined as a distinct function, not an anonymous callback). This function
will receive all events from BackgroundGeolocation
in the headless state, and provided with a HeadlessEvent containing a HeadlessEvent.name and HeadlessEvent.event.
After running your app with runApp
, register your headless-task with registerHeadlessTask. Within your callback
, you're free to interact with the complete BackgroundGeolocation
API.
WARNING: You must registerHeadlessTask
in your main.dart
. Do not place it in your application components.
Example
main.dart
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;
/// Receives all events from BackgroundGeolocation while app is terminated:
void headlessTask(HeadlessEvent headlessEvent) async {
print('[HeadlessTask]: ${headlessEvent}');
// Implement a 'case' for only those events you're interested in.
switch(headlessEvent.name) {
case Event.TERMINATE:
State state = headlessEvent.event;
print('- State: ${state}');
break;
case Event.HEARTBEAT:
HeartbeatEvent event = headlessEvent.event;
print('- HeartbeatEvent: ${event}');
break;
case Event.LOCATION:
Location location = headlessEvent.event;
print('- Location: ${location}');
break;
case Event.MOTIONCHANGE:
Location location = headlessEvent.event;
print('- Location: ${location}');
break;
case Event.GEOFENCE:
GeofenceEvent geofenceEvent = headlessEvent.event;
print('- GeofenceEvent: ${geofenceEvent}');
break;
case Event.GEOFENCESCHANGE:
GeofencesChangeEvent event = headlessEvent.event;
print('- GeofencesChangeEvent: ${event}');
break;
case Event.SCHEDULE:
State state = headlessEvent.event;
print('- State: ${state}');
break;
case Event.ACTIVITYCHANGE:
ActivityChangeEvent event = headlessEvent.event;
print('ActivityChangeEvent: ${event}');
break;
case Event.HTTP:
HttpEvent response = headlessEvent.event;
print('HttpEvent: ${response}');
break;
case Event.POWERSAVECHANGE:
bool enabled = headlessEvent.event;
print('ProviderChangeEvent: ${enabled}');
break;
case Event.CONNECTIVITYCHANGE:
ConnectivityChangeEvent event = headlessEvent.event;
print('ConnectivityChangeEvent: ${event}');
break;
case Event.ENABLEDCHANGE:
bool enabled = headlessEvent.event;
print('EnabledChangeEvent: ${enabled}');
break;
}
}
void main() {
runApp(HelloWorld());
// Register your headlessTask:
BackgroundGeolocation.registerHeadlessTask(headlessTask);
}
Note: The HeadlessEvent.event is of the same class as provided by BackgroundGeolocation's
main event-listeners. You can manually cast this instance as shown in the switch
above.
- onLocation
- onMotionChange
- onHttp
- onActivityChange
- onProviderChange
- onHeartbeat
- onGeofence
- onGeofencesChange
- onEnabledChange
- onConnectivityChange
- onNotificationAction
WARNING:
-
You cannot register more than one headless-task.
-
You cannot reference your UI within your headless-task. There is no UI.
-
Do not register an inline
function
to registerHeadlessTask -- the Flutter framework will fail to address it:
// NO! This will not work.
BackgroundGeolocation.registerHeadlessTask((HeadlessEvent event) {
print('${event}');
});
// YES!
void myHeadlessTask(HeadlessEvent headlessEvent) async {
print('${event}');
}
BackgroundGeolocation.registerHeadlessTask(myHeadlessTask);
Implementation
static Future<bool> registerHeadlessTask(
void Function(HeadlessEvent) callback) async {
Completer completer = Completer<bool>();
// Two callbacks: the provided headless-task + _headlessRegistrationCallback
List<int> args = [
PluginUtilities.getCallbackHandle(_headlessCallbackDispatcher)!
.toRawHandle(),
PluginUtilities.getCallbackHandle(callback)!.toRawHandle()
];
_methodChannel
.invokeMethod<bool>('registerHeadlessTask', args)
.then((bool? success) {
completer.complete(true);
}).catchError((error) {
print('[BackgroundGeolocation registerHeadlessTask] ‼️ $error');
completer.complete(false);
});
return completer.future as FutureOr<bool>;
}