Set up a geofence (HTML)

This topic will guide you through the steps of setting up a Geofence in your app.

Roadmap: How does this topic relate to others? See:

Introduction

There are a number of steps to take when setting up your Geofence. Besides defining the region of interest, you also need to make sure you have the proper location permissions. Finally, you need to set up an event handler in case the user changes those permissions while your app is running.

Verify that location is enabled

Before your app can access location, Location must be enabled on the device. In the Settings app, check that the following location privacy settings are turned on:

  • Location for this device... is turned on (not applicable in Windows 10 Mobile)
  • The location services setting, Location, is turned on
  • Under Choose apps that can use your location, your app is set to on

Enable the location capability

Double click on package.appxmanifest in Solution Explorer and select the Capabilities tab. Then check Location in the Capabilities list. This adds the Location device capability to the package manifest file.

  <Capabilities>
    <!-- DeviceCapability elements must follow Capability elements (if present) -->
    <DeviceCapability Name="location"/>
  </Capabilities>

Check for location permissions

First you may want to add code to your app during initialization to get the location. On Windows, the first time your app uses the API to get the current location, the system will prompt the user for location permission. If your app doesn't have permission from the user, then alert the user. Note that you can still set up a Geofence without location permissions but you won’t receive any notifications until the permissions have been enabled.

    function initialize() {

        promise = geolocator.getGeopositionAsync();
        promise.done(
            function (pos) {
                var coord = pos.coordinate;

            },
            function (err) {
            // handle situations where location permissions are not granted to your app
            }
        );

    }


Listen for location permission changes

Next you want to be sure to register for permission change events, in case the user decides to turn the location permissions off for some reason. First add the event handlers to your initialization method:


var accessInfo = null;
accessInfo = DeviceAccessInformation.createFromDeviceClass(Enumeration.DeviceClass.location);
accessInfo.addEventListener("accesschanged", onAccessChanged);

Then handle the permissions change to let the user know that geofencing will no longer work if location permissions are turned off:

function onAccessChanged(args) {
    var eventDescription = getTimeStampedMessage("Device Access Status");
    var item = null;

    if (DeviceAccessStatus.deniedByUser === args.status) {
        eventDescription += " (DeniedByUser)";

        WinJS.log && WinJS.log("Location has been disabled by the user. Enable access through the settings charm.", "sample", "status");
    } else if (DeviceAccessStatus.deniedBySystem === args.status) {
        eventDescription += " (DeniedBySystem)";

        WinJS.log && WinJS.log("Location has been disabled by the system. The administrator of the device must enable location access through the location control panel.", "sample", "status");
    } else if (DeviceAccessStatus.unspecified === args.status) {
        eventDescription += " (Unspecified)";

        WinJS.log && WinJS.log("Location has been disabled by unspecified source. The administrator of the device may need to enable location access through the location control panel, then enable access through the settings charm.", "sample", "status");
    } else if (DeviceAccessStatus.allowed === args.status) {
        eventDescription += " (Allowed)";

        // clear status
        WinJS.log && WinJS.log("", "sample", "status");
    } else {
        eventDescription += " (Unknown)";

        WinJS.log && WinJS.log("Unknown device access information status", "sample", "status");
    }

    addEventDescription(eventDescription);
}

Note  You can determine if the user has disabled location in Settings by checking the LocationStatus property. If the value is Disabled, then location is disabled.

 

Create the geofence

Now you are ready for define and set up a geofence. Some of the values that can be set for a geofence are:

  • An Id to identify it.
  • The circular region of interest, defined by the Geoshape.
  • The MonitoredStates, which indicate what geofence events you want to receive notifications for - entering the defined region, leaving the defined region, or removal of the geofence.
  • A SingleUse flag, which will remove the geofence once all the states the geofence is being monitored for have been met.
  • A DwellTime, which indicates how long the user must be in or out of the defined area before the enter/exit events are triggered.
  • The StartTime, which indicates when to start monitoring the geofence.
  • The Duration to monitor the geofence for.

function generateGeofence() {
    var geofence = null;

    try {
        var fenceKey = nameElement.value;

        var position = {
            latitude: decimalFormatter.parseDouble(latitude.value),
            longitude: decimalFormatter.parseDouble(longitude.value),
            altitude: 0
        };
        var radiusValue = decimalFormatter.parseDouble(radius.value);

        // the geofence is a circular region
        var geocircle = new Windows.Devices.Geolocation.Geocircle(position, radiusValue);

        var singleUse = false;

        if (geofenceSingleUse.checked) {
            singleUse = true;
        }

        // want to listen for enter geofence, exit geofence and remove geofence events
        var mask = 0;

        mask = mask | Windows.Devices.Geolocation.Geofencing.MonitoredGeofenceStates.entered;
        mask = mask | Windows.Devices.Geolocation.Geofencing.MonitoredGeofenceStates.exited;
        mask = mask | Windows.Devices.Geolocation.Geofencing.MonitoredGeofenceStates.removed;

        var dwellTimeSpan = new Number(parseTimeSpan(dwellTimeField, defaultDwellTimeSeconds));
        var durationTimeSpan = null;
        if (durationField.value.length) {
            durationTimeSpan = new Number(parseTimeSpan(durationField, 0));
        } else {
            durationTimeSpan = new Number(0); // duration needs to be set since start time is set below
        }
        var startDateTime = null;
        if (startTimeField.value.length) {
            startDateTime = new Date(startTimeField.value);
        } else {
            startDateTime = new Date(); // if you don't set start time in JavaScript the start time defaults to 1/1/1601
        }

        geofence = new Windows.Devices.Geolocation.Geofencing.Geofence(fenceKey, geocircle, mask, singleUse, dwellTimeSpan, startDateTime, durationTimeSpan);
    } catch (ex) {
        WinJS.log && WinJS.log(ex.toString(), "sample", "error");
    }

    return geofence;
}

Roadmaps

Roadmap for apps using JavaScript

Designing UX for apps

Tasks

Handle geofence notifications in the foreground

Listen for geofence events in the background

Handle geofence notifications from a background task

Reference

Geoshape

Geofence

Geolocator

Other resources

Windows 10 geolocation sample

Windows 8.1 geolocation sample

Guidelines for geofencing