背景中的地理围栏Windows Phone 8.1(WinRT)

Kia*_*eng 6 windows geolocation windows-runtime windows-phone-8 windows-phone-8.1

问题

我正在尝试在WP8.1(WinRT)中发生地理围栏事件(进入/退出)时触发BackgroundTask.我写了一个示例应用程序试图让它工作,但似乎无法这样做.

到目前为止,这些是我试图让Geofences在后台工作的步骤:

  1. 检查位置功能
  2. 创建+注册地理围栏
  3. 创建+注册一个侦听的BackgroundTask LocationTrigger(LocationTriggerType.Geofence);
  4. 在我的后台任务中,触发一个简单的弹出通知

我在排除故障方面所做的一切

我在我的app.manifest中启用了:

  • Toast Capable =>是的
  • 功能:位置,Internet(客户端和服务器)
  • 声明:BackgroundTasks(位置).EntryPoint =BackgroundTask.GeofenceBackgroundTask

我的后台任务位于一个单独的项目中,标题为BackgroundTask.它是一个WindowsRT组件,包含一个类GeofenceBackgroundTask.

项目布局

示例项目

该项目的代码可以在[link](https://github.com/kiangtengl/GeofenceSample)找到:

如何测试

  1. 在模拟器中运行代码

  2. 将位置设置为:纬度= 01.3369,经度= 103.7364

在此输入图像描述

  1. 单击Register Geofence + BackgroundTasks按钮

  2. 退出应用程序(按主页按钮)

  3. 将当前位置更改为距离您之前设置的位置100米.应该弹出通知.

项目代码:

检查位置功能

    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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

创建地理围栏

    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
        }

    }
Run Code Online (Sandbox Code Playgroud)

注册后台任务

    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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

BackgroundTask代码触发Toast

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Kia*_*eng 3

我发现上面的代码示例以及上面的代码是有效的。我面临的问题是 Windows Phone 8.1 不会自动触发地理围栏事件。在触发BackgroundTask 之前,您必须等待<5 分钟的一定时间。

这也适用于前台的地理围栏。