Geofence Triggers¶
Geofence Triggers are events triggered by the Mobile SDK when a user crosses a virtual boundary (geofence). Geofences can be added through Pointr Cloud Dashboard, which will automatically sync with the Mobile SDK after publishing. The Mobile SDK, based on the device position, determines if a user has entered or exited a geofence.
Types of Geofence¶
Our platform supports two types of geofences:
-
Level Geofence - A virtual boundary added within a specific level. This means that if the geofence is located on level 2 of a building and the user is located on the same geo coordinates of the geofence area but on level 1, the user is outside of the geofence. For this type of geofence to work, indoor positioning is required. Level Geofences are available on the Mobile SDK v8.3.0 onwards.
-
Global Geofence - A virtual boundary with no specific level, only geo coordinates. This means that regardless of being indoors on any level, or outdoors, the user is considered inside the geofence if the geo coordinates are inside the geometry of the geofence. Global Geofences are available on the Mobile SDK v8.5 and onwards.
Configurations¶
Enable/Disable Geofencing¶
Level and Global Geofencing can be enabled/disabled through Pointr Dashboard separately. Both are enabled by default. To change that:
- Go to Pointr Dashboard
- Select the client needed to be edited
- Go to
Advanced Configuration
- Under
SDK
- If not added already, add new parameter by clicking
Add new
button - Enter parameter name:
geofenceManagerConfiguration_IsLevelGeofencingEnabled
for Level andgeofenceManagerConfiguration_IsGlobalGeofencingEnabled
for Global Geofencing - Select Type
Boolean
- Check Value to enable and uncheck to disable.
Confirm
and publish
Other Configurations¶
It is possible to configure other parameters via Pointr Cloud Dashboard. To configure:
- Login to Pointr Cloud Dashboard,
- Click
Edit
button, - Click
Advanced Configuration
button, - Click
Add new
button on SDK section, - Select the relevant parameters on the image below, add the values and then click
Confirm
button.
Note
Geofence configurations apply to all geofences of the same type. For example, changing GeofenceManagerConfiguration_LevelGeofenceDistanceToleranceForExit
is going to have an affect on all level geofences.
Setting up geofence triggers¶
In order to be notified of geofence events, you need to register as a listener of Geofence Manager and implement the method defined on PTRGeofenceManagerDelegate
and GeofenceManager.Listener
for iOS and Android respectively.
NOTE: The SDK does not display local notifications. Geofence Manager only notifies the listeners about the events, so it’s up to the app to display any related UI.
Pointr.getPointr()!!.geofenceManager!!.addListener(object : GeofenceManager.Listener {
override fun onGeofenceManagerGeofenceEvent(event: GeofenceEvent) {
val title = event.geofence.name
// You can add custom values to a geofence on Pointr Cloud Dashboard
val customValue = event.geofence.extraData["customField"]
// Check event type
when(event.type){
GeofenceEventType.Enter -> {
// Handle enter event
displayEnterNotification(title = title, message = customValue)
}
GeofenceEventType.Exit -> {
// Handle exit event
displayExitNotification(title = title, message = customValue)
}
}
// Or check geofence type
when (event.geofence.type) {
GeofenceType.LEVEL -> {
// Handle Level Geofence
}
GeofenceType.GLOBAL -> {
// Handle Global Geofence
}
}
}
})
extension MyClass: PTRGeofenceManagerDelegate {
func listenToGeofenceEvents() {
Pointr.shared.geofenceManager?.addListener(self)
}
func onGeofenceManagerGeofenceEvent(_ event: PTRGeofenceEvent) {
let title = event.geofence.title
// You can add custom values to a geofence on Pointr Cloud Dashboard
let customValue = event.geofence.extraData["customField"]
// Check event type
switch event.type {
case .enter:
// Handle enter event
displayEnterNotification(title: title, message: customValue)
case .exit:
// Handle exit event
displayExitNotification(title: title, message: customValue)
}
// Or check geofence type
switch event.geofence.type {
case .level:
// Handle Level Geofence
case .global:
// Handle Global Geofence
}
}
}
Positioning¶
In order to trigger geofence events, the SDK must have access to the user’s position, so the Position Manager Configuration should be configured accordingly. For more information about changing configuration at runtime check the following link.
val positionManagerConfiguration = Pointr.getPointr()?.configurationManager?.globalConfiguration?.positionManagerConfiguration
if (positionManagerConfiguration?.isCoreLocationEnabled == true && positionManagerConfiguration.isGpsTrackingEnabledInForeground) {
// Indoor and Outdoor positioning enabled on the foreground
}
let positionManagerConfiguration = Pointr.shared.configurationManager?.globalConfiguration().positionManagerConfiguration
if positionManagerConfiguration.isCoreLocationEnabled && positionManagerConfiguration.isGpsTrackingEnabledInForeground {
// Indoor and Outdoor positioning enabled on the foreground
}
Geofencing can work when the application is in foreground or background. However extra permission is needed to make geofencing work in the background. On Android 10 (API level 29) and higher, it is a must to declare the ACCESS_BACKGROUND_LOCATION
permission in the app’s manifest in order to request background location access at runtime for global geofencing. On earlier versions of Android, when your app receives foreground location access, it automatically receives background location access as well.
On iOS, you have to use the key NSLocationAlwaysAndWhenInUseUsageDescription
in your plist
file for background positioning. For more information about permissions check this link.
if positionManagerConfiguration.isBackgroundPositioningEnabled && positionManagerConfiguration.isGpsTrackingEnabledInBackground {
// Indoor and Outdoor positioning also enabled in the background
}
if(positionManagerConfiguration.isBackgroundPositioningEnabled && positionManagerConfiguration.isGpsTrackingEnabledInBackground) {
// Indoor and Outdoor positioning also enabled in the background
}
For Android, background positioning and level geofencing efficiency depend on geofenceManagerConfiguration_scanPeriodBackground
(in miliseconds) and geofenceManagerConfiguration_betweenScanPeriodBackground
(in miliseconds) parameters which are configurable from PC endpoint. During scanPeriod
, SDK scans for beacons and then rests for about betweenScanPeriod
before it goes to the next scanning cycle. For best performance and practices you can check the appropriate values from this link. Scanning period should be at least a little more than 1 second which is 1100 ms by default for foreground scanning. And between scan period is 0 when app is in the foreground by default. You can apply the same values to match the positioning performance even in the background. Having big values for these for background positioning can cause missing and/or misinformed events.
On the example above, person walks in and out of a level geofence and during betweenScanPeriod
when SDK does not listen to beacons hence completely misses both enter and exit events.
Here, person walks into a level geofence during betweenScanPeriod
but SDK detects it only when it comes to scanPeriod
which as a result then reports enter event as the starting time of scanPeriod
.
Geofencing¶
Check if Geofencing is Enabled/Disabled¶
You can check whether the Geofencing is enabled or disabled via the following parameters under Geofence Manager Configuration:
val geofenceManagerConfiguration = Pointr.getPointr()?.configurationManager?.globalConfiguration?.geofenceManagerConfiguration
if (geofenceManagerConfiguration?.isLevelGeofencingEnabled == true) {
// Level geofencing is enabled
}
if (geofenceManagerConfiguration?.isGlobalGeofencingEnabled == true) {
// Global geofencing is enabled
}
let geofenceManagerConfiguration = Pointr.shared.configurationManager?.globalConfiguration().geofenceManagerConfiguration
if geofenceManagerConfiguration.isLevelGeofencingEnabled {
// Level geofencing is enabled
}
if geofenceManagerConfiguration?.isGlobalGeofencingEnabled {
// Global geofencing is enabled
}
Tolerance for enter and exit events¶
You can increase or decrease the size of the geofence specifically for enter and exit events. For example, if you increase the size for exit by entering value 0.1 (which means 10%), it means that the user will get the exit event further away from the geofence boundaries.
levelGeofenceDistanceToleranceForEnter
: Percentage rate to increase the radius of the enclosing circle of the level geofence while resolving enter event.levelGeofenceDistanceToleranceForExit
: Percentage rate to increase the radius of the enclosing circle of the level geofence while resolving exit event.globalGeofenceDistanceToleranceForEnter
: Percentage rate to increase the radius of the enclosing circle of the global geofence while resolving enter event.globalGeofenceDistanceToleranceForExit
: Percentage rate to increase the radius of the enclosing circle of the global geofence while resolving exit event.
Ignore period¶
In order to provide a better experience the SDK does not fire all the events immediately by default. For example, if the user is walking along the boundaries of a geofence, the position could be constantly jumping inside and outside of the boundaries, which would cause consecutive enter and exit events. To avoid this, the SDK sets a ignore period that starts counting from the last triggered event. Example:
Parameters: levelGeofenceIgnorePeriodSinceLastTriggerInSeconds
and globalGeofenceIgnorePeriodSinceLastTriggerInSeconds
NOTE: Ignore period starts counting on each geofence individually.
Case 1:
- SDK sets default ignore period, 30 seconds
- User enters the geofence and geofence manager triggers an enter event
- 30 seconds ignore period starts
- User leaves the geofence 40 seconds after the enter
- User gets exit trigger
Case 2:
- SDK sets default ignore period, 30 seconds
- User enters the geofence and geofence manager triggers an enter event
- 30 seconds ignore period starts
- User leaves and enters the geofence constantly in small periods of time (less than 30s)
- For every enter and exit, ignore period is reset to 30 seconds
- User finally leaves the geofence
- User gets exit trigger 30 seconds after final exit
Warning
Beacon geofencing works in the background if user has given ACCESS_BACKGROUND_LOCATION
permission for Android and NSLocationAlwaysAndWhenInUseUsageDescription
permission for iOS.
Platform limitations for Global Geofencing¶
The Pointr Mobile SDK uses native geofencing APIs from iOS and Android to get geofence events. Both platforms have a maximum number of geofences that can be monitored at the same time. Since the host application can also monitor for geofences directly (not using the SDK), both SDK and host application share the maximum number allowed.
Maximum allowed: 100 geofences
Geofence Manager Configuration parameter: geofencesToRegisterMaxCountAndroid
By default, the SDK also allows 100 geofences to be monitored at the same time. In case the host application also needs to monitor geofences directly, you can set a new max for the SDK.
Maximum allowed: 20 geofences
Geofence Manager Configuration parameter: geofencesToRegisterMaxCountIos
By default, the SDK allows 10 geofences to be monitored at the same time. In case the host application also needs to monitor geofences directly, you can set a new max for the SDK.
Note
On iOS the beacon’s UUIDs monitored for indoor positioning also count for the max 20 allowed by the system, so we set 10 for Global Geofences and another 10 for beacons.
Note
The system allows for up to 20 geofences, but there’s no limit to adding more. Despite the 20 geofences restriction, we consistently check the closest 10 geofences as the user moves. These limitations have no impact on the clients.
Get geofences events when app is not running¶
When your app has been manually or automatically terminated, you can still get location updates and geofence events from Pointr.
On iOS, in order to achieve it, you have to make sure the Pointr SDK is initialized when the system “wakes up” the app to deliver those events. To know if the system is launching the app to deliver a location related event you should check the launch options as in the following example:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if launchOptions?[.location] != nil {
// Start Pointr
}
return true
}
On Android, to continue to get location updates and geofence events even when the app is killed, you have to make sure the Pointr SDK is started as a foreground service. To start SDK as foreground service you should call the appropriate function as in the following example. You should still need to initialize SDK before calling startAsForegroundService
. Second parameter of startAsForegroundService
is used to acquire a wake lock to keep CPU on:
val params = PointrServiceParams(
"Pointr Service Title",
"Pointr Service Description",
com.pointrlabs.core.R.drawable.pointr_mark,
(YourActivity::class.java)
)
Pointr.getPointr()?.startAsForegroundService(params, true)