Flutter
Published in

Flutter

Executing Dart in the Background with Flutter Plugins and Geofencing

No garage door remote? Not a problem with Flutter and a Raspberry Pi!

Table of Contents

Geofencing: defining the Dart API

  • The ability to create instances of GeofenceRegion, which contain the coordinates and radius of a geofence, a unique ID, and a list of geofencing events to listen for. Since Android provides a richer set of options for defining geofences than iOS, Android-specific options are made available through the optional androidSettings property.
  • GeofencingPlugin.registerGeofence allows for the registration of a GeofenceRegion instance with a callback that is invoked when a geofence event for that region is received.
  • GeofencingPlugin.removeGeofence and GeofencingPlugin.removeGeofenceById unregister a GeofenceRegion from triggering additional events.

Dart background execution

Referencing Callbacks

Callback handles are managed by the Flutter engine and can be used to reference and lookup callbacks across isolates.

The Callback Dispatcher

  • An instance of List<String> for the IDs of the geofences that were triggered
  • An instance of Location describing the current location of the device
  • An instance of the GeofenceEvent enum that represents whether the device has entered, exited, or dwelled within the triggered geofences.

Background execution: Android (Kotlin)

  • The GeofencingPlugin class, which is registered with the Flutter engine in order to receive and handle method calls made from Dart code
  • A GeofencingBroadcastReceiver, which is invoked by the system on a geofence event
  • The GeofencingService, which creates the background isolate, initializes the callback dispatcher described earlier, and processes geofence events before invoking the callback dispatcher.

GeofencingPlugin

  • FlutterPlugin: declares onAttachedToEngine and onDetachedFromEngine, used to notify the plugin of its connection status to a Flutter engine instance.
  • MethodCallHandler: declares onMethodCall, the method used to process messages sent to the plugin over a MethodChannel.

Creating Geofences

  1. Pull the relevant arguments out of the ArrayList sent over the MethodChannel
  2. Create an instance of Geofence that describes the location and size of the geofence as well as its various trigger parameters
  3. Before registering the Geofence instance, do another check to ensure that the application still has the correct device permissions for geofencing
  4. Finally, a GeofencingRequest as well as a PendingIntent are created and used to register the geofence. The PendingIntent is used to invoke the GeofencingBroadcastReceiver when the geofence is triggered; it contains the callback handle associated with that geofence.

Scheduling the geofencing service

Handling Geofence Events

Background execution: iOS (Objective-C)

Initializing the plugin

Starting the callback dispatcher

Handling method calls

Registering geofences

Handling geofence events

Geofence events in a suspended state

Usage example: operating a garage door with geofencing

The relay is triggered by the Raspberry Pi, which opens and closes the door (left). A proximity sensor allows for the garage door service to know whether or not the door is currently open (right).
My garage door remote, built using Flutter. Can you tell that I’m a backend engineer?

Setting the right permissions

Permissions: Android

Permissions: iOS

Bringing it all together

Conclusion

Like many members of the Dart and Flutter teams, Dash loves cycling. However, for obvious reasons, Dash has a bit of trouble riding a bike.

Resources

Docs for Dart:

  • PluginUtilities: contains methods for dealing with CallbackHandles
  • IsolateNameServer: establishing communication between foreground and background isolates using named SendPorts

Docs for Android:

Docs for iOS:

  • FlutterEngine: allows for spawning a background isolate
  • FlutterCallbackCache: lookup callback information needed for starting a background isolate using callback handles

Sample Plugins:

Projects referenced:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ben Konyi

Ben Konyi

513 Followers

Google Software Engineer — Dart VM Hacker, Flutter Runtime Dev, Amateur Cyclist, and Proud Canadian 🍁