Search code examples
c#azurewindows-10-universalwindows-10-mobile

BackgroundTask geofence triggering


I am trying to showToast when the phone leaves or enter the geofenced location (which is set elsewhere and passed in). The issue is that when the app is in the background the trigger does not occur and I don't see the showToast message. I am changing the location manually using an emulator on my PC.

Background Tasks> Location is set under the app manifest.

This is the code I am using to build the Geofence and backgroundtask

//Creates Geofence and names it "PetsnikkerVacationFence"
public static async Task SetupGeofence(double lat, double lon)
    {
        await RegisterBackgroundTasks();

        if (IsTaskRegistered())
        {

            BasicGeoposition position = new BasicGeoposition();
            position.Latitude = lat;
            position.Longitude = lon;

            double radius = 8046.72; //5 miles in meters
            Geocircle geocircle = new Geocircle(position, radius);
            MonitoredGeofenceStates monitoredStates = MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited;

            Geofence geofence = new Geofence("PetsnikkerVacationFence", geocircle, monitoredStates, false);

            GeofenceMonitor monitor = GeofenceMonitor.Current;

            var existingFence = monitor.Geofences.SingleOrDefault(f => f.Id == "PetsnikkerVacationFence");

            if (existingFence != null)
                monitor.Geofences.Remove(existingFence);

            monitor.Geofences.Add(geofence);

        }




    }

    //Registers the background task with a LocationTrigger
    static async Task RegisterBackgroundTasks()
    {
        var access = await BackgroundExecutionManager.RequestAccessAsync();


        if (access == BackgroundAccessStatus.Denied)
        {

        }
        else
        {
            var taskBuilder = new BackgroundTaskBuilder();
            taskBuilder.Name = "PetsnikkerVacationFence";

            taskBuilder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
            taskBuilder.SetTrigger(new LocationTrigger(LocationTriggerType.Geofence));

            taskBuilder.TaskEntryPoint = typeof(Petsnikker.Windows.Background.GeofenceTask).FullName;

            var registration = taskBuilder.Register();

            registration.Completed += (sender, e) =>
            {
                try
                {
                    e.CheckResult();
                }
                catch (Exception error)
                {
                    Debug.WriteLine(error);
                }
            };



        }

    }

    static bool IsTaskRegistered()
    {
        var Registered = false;
        var entry = BackgroundTaskRegistration.AllTasks.FirstOrDefault(keyval => keyval.Value.Name == "PetsnikkerVacationFence");
        if (entry.Value != null)
            Registered = true;
        return Registered;
    }
}
}

This code is where I monitor the state of the geofence. This is where the Entry point in the appxmanifest is pointing

public sealed class GeofenceTask : IBackgroundTask
{
    public void Run(IBackgroundTaskInstance taskInstance)
    {

        var monitor = GeofenceMonitor.Current;
        if (monitor.Geofences.Any())
        {
            var reports = monitor.ReadReports();
            foreach (var report in reports)
            {


                switch (report.NewState)
                {
                    case GeofenceState.Entered:
                    {

                            ShowToast("Approaching Home",":-)");
                            break;
                    }
                    case GeofenceState.Exited:
                    {
                            ShowToast("Leaving Home", ":-)");
                            break;


                    }


                }
            }
        }


        //deferral.Complete();
    }

    private static void ShowToast(string firstLine, string secondLine)
    {
        var toastXmlContent =
          ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);

        var txtNodes = toastXmlContent.GetElementsByTagName("text");
        txtNodes[0].AppendChild(toastXmlContent.CreateTextNode(firstLine));
        txtNodes[1].AppendChild(toastXmlContent.CreateTextNode(secondLine));

        var toast = new ToastNotification(toastXmlContent);
        var toastNotifier = ToastNotificationManager.CreateToastNotifier();
        toastNotifier.Show(toast);

        Debug.WriteLine("Toast: {0} {1}", firstLine, secondLine);
    }

}

Solution

  • After looking at your code, it seems that your code is correct.

    In order to fire the Geofence Backgroundtask to show the toast information, please make sure the following things:

    1) Please make sure that you have done all the necessary configuration in the Package.appxmanifest for registering the BackgroundTask, for example you have set the correct EntryPoint and added the “Location” capabilities.

    For the detailed information, you can try to compare your Package.appxmanifest with the official sample Geolocation’s Package.appxmanifest. Please also check: Create and register a background task and Declare background tasks in the application manifest.

    2) Please make sure that you know how to set the location in the Emulator manually for simulating the phone leave or enter the geofenced location. For more information about how to set location in the emulator, please check the following article: https://msdn.microsoft.com/library/windows/apps/dn629629.aspx#location_and_driving .

    3) Please make sure that your second position in your emulator is not really far away from the geofences that you have defined in the first time, because the emulator behaves like a real device, and the device doesn’t expect to suddenly move from New York to Seattle. Or the BackgroundTask will not be fire immediately.

    4) Background tasks for geofencing cannot launch more frequently than every 2 minutes. If you test geofences in the background, the emulator is capable of automatically starting background tasks. But for the next subsequent background tasks, you need to wait for more than 2 minutes.

    Besides, I will recommend you refer to the following article about how to use the Windows Phone Emulator for testing apps with geofencing: https://blogs.windows.com/buildingapps/2014/05/28/using-the-windows-phone-emulator-for-testing-apps-with-geofencing/ .

    Thanks.