geofencing_flutter_plugin
This Flutter plugin extends the functionality offered by the Woosmap Geofencing Mobile SDKs. Find more about the Woosmap Geofencing SDK.
Android | iOS | |
---|---|---|
Support SDK | 33+ | 13.0+ |
Supported Platforms
- iOS
- Android
Modules
- GeofencingFlutterPlugin: Contains methods to monitor location, regions and POIs.
Objects
- Location: Represents the location object.
- POI: Represents Point of Interest.
- Region: Represents a geographical region/geofence.
- GeofenceRegion: Used while adding a new region in the local database.
Types
- ProfileSource: Represents tracking profile source. It can either be
ProfileSource.local
andProfileSource.external
- RegionType: Represents the type of the region. Possible values are
RegionType.circle
andRegionType.isochrone
Usage
import 'package:geofencing_flutter_plugin/geofencing_flutter_plugin.dart';
final geofencingFlutterPlugin = GeofencingFlutterPlugin();
// ...
Check and request permissions
Before initializing the SDK it is required that you request for required location permissions.
To check if the location permissions are granted by the user call getPermissionsStatus
method.
Future<String?> returnVal = geofencingFlutterPlugin.getPermissionsStatus();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Parameter status will be a string, one of:
GRANTED_BACKGROUND
: User has granted location access even when app is not running in the foreground.GRANTED_FOREGROUND
: Location access is granted only while user is using the app.DENIED
: Location access is denied.UNKNOWN
: Without providing or denying any permission then it will return unknown.
Please note: Plugin will not work as expected if location access is denied.
Requesting location access
To request location access call requestPermissions
method of the plugin. This will result in displaying location access permission dialog. This method accepts a boolean parameter background
. If this parameter is set to true, then plugin will ask for background location access. Code snippet below asks for background location access.
Future<String?> returnVal = geofencingFlutterPlugin.requestPermissions(background);
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Check Bluetooth permissions
In order to get beacon-fencing running on Android devices you need to make sure that all the Bluetooth related permissions are granted to the plugin.
To check if the Bluetooth permissions are granted by the user call getBLEPermissionsStatus
method.
Future<String?> returnVal = geofencingFlutterPlugin.getBLEPermissionsStatus();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Parameter status will be a string, one of:
GRANTED
: User has granted bluetooth access.DENIED
: Bluetooth access is denied.BACKGROUND_LOCATION_DENIED
: Background location access is denied. You first need to request background location permission.
Requesting Bluetooth permissions
To request Bluetooth access call requestBLEPermissions
method of the plugin. This will result in displaying Bluetooth access permission dialog.
Future<String?> returnVal = geofencingFlutterPlugin.requestBLEPermissions();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Note: For beacon-fencing to work you will also need to request background location access. To request background location access please invoke requestPermissions
method of the plugin with background parameter enabled.
Initializing the plugin
Plugin can be initialized by simply calling initialize
method.
Map<String, String> woosmapSettings = {
"privateKeyWoosmapAPI": "<<WOOSMAP_KEY>>",
"trackingProfile": "liveTracking"
};
Future<String?> returnVal = geofencingFlutterPlugin.initialize(woosmapSettings);
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: $error');
});
Both configuration options privateKeyWoosmapAPI
and trackingProfile
are optional. You can also initialize the plugin by passing null configuration.
Future<String?> returnVal = geofencingFlutterPlugin.initialize();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: $error');
});
You can also set the Woosmap API key later by calling setWoosmapApiKey
method.
Future<String?> returnVal = geofencingFlutterPlugin.setWoosmapApiKey("<<WOOSMAP_KEY>>");
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Tracking
Once you have initialized the plugin and the user has authorized location permissions, you can start tracking the user’s location.
To start tracking, call:
Future<String?> returnVal = geofencingFlutterPlugin.startTracking('liveTracking');
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
To stop tracking, call:
Future<String?> returnVal = geofencingFlutterPlugin.stopTracking();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Method startTracking
accepts only following tracking profiles
- liveTracking
- passiveTracking
- visitsTracking
- beaconTracking
Tracking profile properties
Property | liveTracking | passiveTracking | visitsTracking |
---|---|---|---|
trackingEnable | true | true | true |
foregroundLocationServiceEnable | true | false | false |
modeHighFrequencyLocation | true | false | false |
visitEnable | false | false | true |
classificationEnable | false | false | true |
minDurationVisitDisplay | null | null | 300 |
radiusDetectionClassifiedZOI | null | null | 50 |
distanceDetectionThresholdVisits | null | null | 25 |
currentLocationTimeFilter | 0 | 0 | 0 |
currentLocationDistanceFilter | 0 | 0 | 0 |
accuracyFilter | 100 | 100 | 100 |
searchAPIEnable | false | true | false |
searchAPICreationRegionEnable | false | true | false |
searchAPITimeFilter | 0 | 0 | 0 |
searchAPIDistanceFilter | 0 | 0 | 0 |
distanceAPIEnable | false | false | false |
modeDistance | null | null | null |
outOfTimeDelay | 300 | 300 | 300 |
DOUBLEOfDayDataDuration | 30 | 30 | 30 |
Listening to events
Location
To listen to location, call watchLocation
method. After successful invokation of the method you'll need to call getWatchLocationStream
method which will return a stream of Location
object. Once you obtain the stream call the listen
method of the stream.
Future<String?> returnVal = geofencingFlutterPlugin.watchLocation();
returnVal.then((value){
//Get the location stream
watchLocationStream = geofencingFlutterPlugin.getWatchLocationStream();
//Listen to the stream
watchLocationStream.listen((location){
//Location updates will be recieved here.
if (location != null) {
debugPrint(location.locationDescription);
} else {
debugPrint("Location is null");
}
});
}).catchError((error) {
debugPrint('An error occurred: $error');
});
To stop getting location updates:
Future<String?> returnVal = geofencingFlutterPlugin.clearLocationWatch();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: $error');
});
Define the radius value
When you create a Geofence around a POI (previously imported from Woosmap), manually define the radius value:
Future<String?> returnVal = _geofencingFlutterPlugin.setPoiRadius("100");
returnVal.then((value){
showToast(value!);
}).catchError((error) {
showToast('An error occurred: ${error.message}');
});
or choose the user_properties subfield that corresponds to radius value of the Geofence:
Future<String?> returnVal = _geofencingFlutterPlugin.setPoiRadius("radiusPOI");
returnVal.then((value){
showToast(value!);
}).catchError((error) {
showToast('An error occurred: ${error.message}');
});
Regions
Call watchRegions
method to track Regions. Method will invoke a callback with Region object. Method will return a watch id which can be used later to remove the callback.
Future<String?> returnVal = geofencingFlutterPlugin.watchRegion();
returnVal.then((value){
//Get the region stream
watchRegionStream = geofencingFlutterPlugin.getWatchRegionStream();
//Listen to the stream
watchRegionStream.listen((region){
//Region updates will be recieved here.
if (location != null) {
debugPrint(region.eventName);
} else {
debugPrint("Region is null");
}
});
}).catchError((error) {
debugPrint('An error occurred: $error');
});
To remove watch:
Future<String?> returnVal = geofencingFlutterPlugin.clearRegionWatch();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: $error');
});
Initialize Salesforce MarketingCloud Connector
The SDK needs some input like credentials and object key to perform the API call to Salesforce Marketing Cloud API.
Input to initialize the SFMC connector
Parameters | Description | Required |
---|---|---|
authenticationBaseURI | Authentication Base URI | Required |
restBaseURI | REST Base URI | Required |
client_id | client_id (journey_read and list_and_subscribers_read rights are required) | Required |
client_secret | client_secret (journey_read and list_and_subscribers_read rights are required) | Required |
contactKey | The ID that uniquely identifies a subscriber/contact | Required |
regionEnteredEventDefinitionKey | Set the EventDefinitionKey that you want to use for the Woosmap event woos_geofence_entered_event |
|
regionExitedEventDefinitionKey | Set the EventDefinitionKey that you want to use for the Woosmap event woos_geofence_exited_event |
|
poiEventDefinitionKey | Set the EventDefinitionKey that you want to use for the Woosmap event woos_POI_event |
|
zoiClassifiedEnteredEventDefinitionKey | Set the EventDefinitionKey that you want to use for the Woosmap event woos_zoi_classified_entered_event |
|
zoiClassifiedExitedEventDefinitionKey | Set the EventDefinitionKey that you want to use for the Woosmap event woos_zoi_classified_exited_event |
|
visitEventDefinitionKey | Set the EventDefinitionKey that you want to use for the Woosmap event woos_Visit_event |
Initialize the connector implementation
Map<String, String> arguments = {
'authenticationBaseURI': config.authenticationBaseURI,
'restBaseURI':config.restBaseURI,
'client_id': config.clientId,
'client_secret': config.clientSecret,
'contactKey': config.contactKey,
'regionEnteredEventDefinitionKey': config.regionEnteredEventDefinitionKey,
'regionExitedEventDefinitionKey':config.regionExitedEventDefinitionKey,
};
Future<String?> returnVal = geofencingFlutterPlugin.setSFMCCredentials(arguments);
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Adding and removing regions
Call addRegion
method to add a region that you want to monitor.
Region type can be circle
or isochrone
only.
Method will accept an object with the following attributes:
- regionId - Id of the region
- lat - Latitude
- lng - Longitude
- radius - Radius in meters
- type - type of region
Create a custom circle region
GeofenceRegion geofenceRegion = GeofenceRegio(
'7F91369E-467C-4CBD-8D41-6509815C4780',
51.50998,
-0.1337,
180,
RegionType.circle
);
Future<String?> returnVal = geofencingFlutterPlugin.addRegion(geofenceRegion);
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Create a custom isochrone region
GeofenceRegion geofenceRegion = GeofenceRegio(
'7F91369E-467C-4CBD-8D41-6509815C4780',
51.50998,
-0.1337,
180,
RegionType.isochrone
);
Future<String?> returnVal = geofencingFlutterPlugin.addRegion(geofenceRegion);
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Call removeRegions
method to remove a region that you are monitoring. Method will accept the following parameter, and passing a null value will remove all the regions.
Future<String?> returnVal = geofencingFlutterPlugin.removeRegions('7F91369E-467C-4CBD-8D41-6509815C4780');
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Or To Delete all Regions
Future<String?> returnVal = geofencingFlutterPlugin.removeRegions();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Local database operations
- Get POIs: Call
getPois
method to get an array of POIs from the local db
// Get single POI
Future<List<Poi>?> returnVal = geofencingFlutterPlugin.getPois(poiId);
returnVal.then((pois){
if (pois != null){
debugPrint('POIs: ${pois.length}');
}
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
// Get all POIs
Future<List<Poi>?> returnVal = geofencingFlutterPlugin.getPois();
returnVal.then((pois){
if (pois != null){
debugPrint('POIs: ${pois.length}');
}
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
- Delete POIs: Call
removePois
method to clear all POIs from the local db.
Future<String?> returnVal = geofencingFlutterPlugin.removePois();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
- Refresh POIs: Call
refreshPois
method to fetch updated POI information from Woosmap API.
Future<String?> returnVal = geofencingFlutterPlugin.refreshPois();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
- Get Locations: Call
getLocations
method to get an array of Locations from the local db.
//Get single location
Future<List<Location>?> returnVal = geofencingFlutterPlugin.getLocations(locationId);
returnVal.then((locations){
if (locations != null){
debugPrint('Locations: ${locations.length}');
}
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
//Get all locations
Future<List<Location>?> returnVal = geofencingFlutterPlugin.getLocations();
returnVal.then((locations){
if (locations != null){
debugPrint('Locations: ${locations.length}');
}
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
- Delete Locations: Call
removeLocations
method to clear all Locations info from the local db.
Future<String?> returnVal = geofencingFlutterPlugin.removeLocations();
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
- Get Regions: Call
getRegions
method to get an array of Regions from the local db. specify region id to retrieve specific region info
//Get single region
Future<List<Region>?> returnVal = geofencingFlutterPlugin.getRegions(regionId);
returnVal.then((regions){
if (regions != null){
debugPrint('Regions: ${regions.length}');
}else{
debugPrint('Regions is null');
}
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
//Get all regions
Future<List<Region>?> returnVal = geofencingFlutterPlugin.getRegions();
returnVal.then((regions){
if (regions != null){
debugPrint('Regions: ${regions.length}');
}else{
debugPrint('Regions is null');
}
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
- Get Indoor Beacons: Call
getIndoorBeacons
method to get a list ofIndoorBeacon
from the local db. You can pass avenueId
to get the beacons for a specific venue or you can passref
parameter which will get a beacon with specific identifier or you can pass both.
Future<List<IndoorBeacon>?> returnVal;
returnVal = geofencingFlutterPlugin.getIndoorBeacons(); //Get all indoor beacons
returnVal = geofencingFlutterPlugin.getIndoorBeacons(venueID: "YOUR-VENUE-ID"); //Get beacons for a venue
returnVal = geofencingFlutterPlugin.getIndoorBeacons(ref: "BEACON-IDENTIFIER"); //Get beacon with an identifier
returnVal = geofencingFlutterPlugin.getIndoorBeacons(venueID: "YOUR-VENUE-ID", ref: "BEACON-IDENTIFIER"); //Filter by both
returnVal.then((beacons) {
if (beacons != null) {
debugPrint('Indoor beacons: ${beacons.length}');
}
}).catchError((error) {
showToast('An error occurred: ${error.message}');
});
- Delete Indoor Beacons: Call
removeIndoorBeacons
method to delete all indoor beacons from the local DB.
Future<String?> returnVal = geofencingFlutterPlugin.removeIndoorBeacons();
returnVal.then((value) {
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Custom tracking profile
If preset tracking profiles don’t fit with your use cases, you can build your own profile and uses the startCustomTracking() method. There are two way to host the json file:
- Include json file in the client application (local) for ios.
- For local mode put json file in assets folder in android.
- Host externally in a file folder in your information system (external)
Future<String?> returnVal = geofencingFlutterPlugin.startCustomTracking(ProfileSource.local, 'localProfile.json');
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
or
Future<String?> returnVal = geofencingFlutterPlugin.startCustomTracking(ProfileSource.external, 'https://raw.githubusercontent.com/lpernelle-wgs/files/master/customProfileLeo.json');
returnVal.then((value){
debugPrint(value!);
}).catchError((error) {
debugPrint('An error occurred: ${error.message}');
});
Build a custom tracking profile
Define tracking properties in a Json file that respect the Json Schema in the Tracking properties page.
License
BSD-3