-
Notifications
You must be signed in to change notification settings - Fork 249
Android Headless Mode
The BackgroundGeolocation SDK provides an Android Headless Mechanism, enabled with Config.enableHeadless: true
. Doing so allows you to provide your own dart
callback to receive events after your app has been terminated.
ℹ️ iOS has no concept of "Headless". When an iOS app is launched in the background, due to a geofence event for example, the entire app is launched in the background, just as if launched from the home-screen icon.
If you intend to use the SDK's Android Headless mechanism, you must perform the following additional setup:
Create either Application.kt
or Application.java
in the same directory as MainActivity
.
package your.app.name
with your app's package name. If you don't know your package name, you can find it at the 1st line in MainActivity.java
.
- For
Application.java
, use the following:
package your.app.name; // <-- replace this
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant;
import com.transistorsoft.flutter.backgroundgeolocation.FLTBackgroundGeolocationPlugin;
public class Application extends FlutterApplication implements PluginRegistry.PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
FLTBackgroundGeolocationPlugin.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
- For
Application.kt
, use the following:
package your.app.name; // <-- replace this
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant;
import com.transistorsoft.flutter.backgroundgeolocation.FLTBackgroundGeolocationPlugin;
class Application : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {
override fun onCreate() {
super.onCreate();
FLTBackgroundGeolocationPlugin.setPluginRegistrant(this);
}
override fun registerWith(registry: PluginRegistry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
Now edit AndroidManifest.xml
and provide a reference to your custom Application
class:
<application
android:name=".Application"
...
Open your main.dart
file. Create a global function to receive headless events:
main.dart
. Do not attempt to create the headless-task in your Application component.
📂 main.dart
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;
void headlessTask(bg.HeadlessEvent headlessEvent) async {
print('[BackgroundGeolocation HeadlessTask]: $headlessEvent');
// Implement a 'case' for only those events you're interested in.
switch(headlessEvent.name) {
case bg.Event.TERMINATE:
bg.State state = headlessEvent.event;
print('- State: $state');
break;
case bg.Event.HEARTBEAT:
bg.HeartbeatEvent event = headlessEvent.event;
print('- HeartbeatEvent: $event');
break;
case bg.Event.LOCATION:
bg.Location location = headlessEvent.event;
print('- Location: $location');
break;
case bg.Event.MOTIONCHANGE:
bg.Location location = headlessEvent.event;
print('- Location: $location');
break;
case bg.Event.GEOFENCE:
bg.GeofenceEvent geofenceEvent = headlessEvent.event;
print('- GeofenceEvent: $geofenceEvent');
break;
case bg.Event.GEOFENCESCHANGE:
bg.GeofencesChangeEvent event = headlessEvent.event;
print('- GeofencesChangeEvent: $event');
break;
case bg.Event.SCHEDULE:
bg.State state = headlessEvent.event;
print('- State: $state');
break;
case bg.Event.ACTIVITYCHANGE:
bg.ActivityChangeEvent event = headlessEvent.event;
print('ActivityChangeEvent: $event');
break;
case bg.Event.HTTP:
bg.HttpEvent response = headlessEvent.event;
print('HttpEvent: $response');
break;
case bg.Event.POWERSAVECHANGE:
bool enabled = headlessEvent.event;
print('ProviderChangeEvent: $enabled');
break;
case bg.Event.CONNECTIVITYCHANGE:
bg.ConnectivityChangeEvent event = headlessEvent.event;
print('ConnectivityChangeEvent: $event');
break;
case bg.Event.ENABLEDCHANGE:
bool enabled = headlessEvent.event;
print('EnabledChangeEvent: $enabled');
break;
}
}
void main() {
runApp(HelloWorld());
// Register your headlessTask:
BackgroundGeolocation.registerHeadlessTask(headlessTask);
}
- 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
toregisterHeadlessTask
— the Flutter framework will fail to reference it:
// NO! This will not work.
BackgroundGeolocation.registerHeadlessTask((HeadlessEvent event) {
print('$event');
});
// YES!
void myHeadlessTask(HeadlessEvent headlessEvent) async {
print('$event');
}
In your Application component, where you execute BackgroundGeolocation.ready
, add the option enableHeadless: true
:
registerHeadlessTask
here in your Application components — it will never work.
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;
class HelloWorldPage extends StatefulWidget {
HelloWorldPage({Key key}) : super(key: key);
@override
_HelloWorldPageState createState() => new _HelloWorldPageState();
}
class _HelloWorldPageState extends State<HelloWorldPage> {
@override
void initState() {
super.initState();
_initPlatformState();
}
Future<Null> _initPlatformState() async {
bg.BackgroundGeolocation.onLocation((Location location) {
print('[onLocation] $location');
});
bg.BackgroundGeolocation.ready(bg.Config(
enableHeadless: true,
stopOnTerminate: false,
startOnBoot: true
));
}
}