I'm trying to trigger a BackgroundTask when a Geofence Event (Enter / Exit) occurs in WP8.1 (WinRT). I've written a sample application to try to get it working, but can't seem to be able to do so.
So far, these are the steps I've taken to try to get Geofences working in the background:
LocationTrigger(LocationTriggerType.Geofence);
I have enabled in my app.manifest:
BackgroundTask.GeofenceBackgroundTask
My background task is located in a separate project, titled BackgroundTask
. It is a WindowsRT Component and contains one class GeofenceBackgroundTask
.
The code for the project can be found at this [link](https://github.com/kiangtengl/GeofenceSample):
Run the code in the emulator
Set Location to to: Latitude = 01.3369, Longitude = 103.7364
Click the Register Geofence + BackgroundTasks button
Exit the app (press the home button)
Change the current location to anywhere 100m away from the location you set previously. A notification should pop out.
public static async Task GetLocationCapabilities()
{
try
{
var geolocator = new Geolocator();
await geolocator.GetGeopositionAsync();
var backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
Debug.WriteLine("background access status" + backgroundAccessStatus);
}
catch (UnauthorizedAccessException e)
{
Debug.WriteLine(e);
}
catch (TaskCanceledException e)
{
Debug.WriteLine(e);
}
}
public static void CreateGeofence(BasicGeoposition position, double radius, string id = "default")
{
// The Geofence is a circular area centered at (latitude, longitude) point, with the
// radius in meter.
var geocircle = new Geocircle(position, radius);
// Sets the events that we want to handle: in this case, the entrace and the exit
// from an area of intereset.
var mask = MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited;
// Specifies for how much time the user must have entered/exited the area before
// receiving the notification.
var dwellTime = TimeSpan.FromSeconds(1);
// Creates the Geofence and adds it to the GeofenceMonitor.
var geofence = new Geofence(id, geocircle, mask, false, dwellTime);
try
{
GeofenceMonitor.Current.Geofences.Add(geofence);
}
catch (Exception e)
{
Debug.WriteLine(e);
// geofence already added to system
}
}
public static async Task RegisterBackgroundTask()
{
try
{
// Create a new background task builder
var geofenceTaskBuilder = new BackgroundTaskBuilder()
{
Name = GeofenceBackgroundTaskName,
TaskEntryPoint = "BackgroundTask.GeofenceBackgroundTask"
};
// Create a new location trigger
var trigger = new LocationTrigger(LocationTriggerType.Geofence);
// Associate the location trigger with the background task builder
geofenceTaskBuilder.SetTrigger(trigger);
var geofenceTask = geofenceTaskBuilder.Register();
// Associate an event handler with the new background task
geofenceTask.Completed += (sender, e) =>
{
try
{
e.CheckResult();
}
catch(Exception error)
{
Debug.WriteLine(error);
}
};
}
catch(Exception e)
{
// Background task probably exists
Debug.WriteLine(e);
}
}
namespace BackgroundTask
{
public sealed class GeofenceBackgroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
var toastTemplate = ToastTemplateType.ToastText02;
var toastXML = ToastNotificationManager.GetTemplateContent(toastTemplate);
var textElements = toastXML.GetElementsByTagName("text");
textElements[0].AppendChild(toastXML.CreateTextNode("You have left!"));
var toast = new ToastNotification(toastXML);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
}
}
I've discovered that the above code sample, as well as the above code works. The problem that I was facing was that Windows Phone 8.1 does not automatically trigger a Geofence event. You have to wait a certain amount of time <5 mins before the BackgroundTask is triggered.
This applies to Geofencing in the foreground as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With