Skip to content

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.

Geofence Triggers Intro

Types of Geofence

Our platform supports two types of geofences:

  1. 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.

  2. 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 and geofenceManagerConfiguration_IsGlobalGeofencingEnabled for Global Geofencing
  • Select Type Boolean
  • Check Value to enable and uncheck to disable.
  • Confirm and publish

Enable/Disable Geofencing

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.

Missed level geofence

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.

Misinformed level geofence

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.

  1. levelGeofenceDistanceToleranceForEnter: Percentage rate to increase the radius of the enclosing circle of the level geofence while resolving enter event.
  2. levelGeofenceDistanceToleranceForExit: Percentage rate to increase the radius of the enclosing circle of the level geofence while resolving exit event.
  3. globalGeofenceDistanceToleranceForEnter: Percentage rate to increase the radius of the enclosing circle of the global geofence while resolving enter event.
  4. globalGeofenceDistanceToleranceForExit: Percentage rate to increase the radius of the enclosing circle of the global geofence while resolving exit event.

Tolerance for geofencing

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:

  1. SDK sets default ignore period, 30 seconds
  2. User enters the geofence and geofence manager triggers an enter event
  3. 30 seconds ignore period starts
  4. User leaves the geofence 40 seconds after the enter
  5. User gets exit trigger

Case 2:

  1. SDK sets default ignore period, 30 seconds
  2. User enters the geofence and geofence manager triggers an enter event
  3. 30 seconds ignore period starts
  4. User leaves and enters the geofence constantly in small periods of time (less than 30s)
  5. For every enter and exit, ignore period is reset to 30 seconds
  6. User finally leaves the geofence
  7. User gets exit trigger 30 seconds after final exit

Geofence Triggers Case 2

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)

Last update: February 19, 2024
Back to top