在Windows 10上使用UWP Geolocation-API和Win32-Application

时间:2016-08-19 13:03:44

标签: c# .net winapi windows-10 uwp

我们正在构建面向Windows 8.1和10的多平台(台式机和平板电脑)应用程序。当我们处理空间数据时,我们为用户提供使用设备的gps接收器使用其当前位置的可能性。为了便于适应(硬件)环境,我们将gps-logic(包括API调用)放入我们根据配置加载的外部程序集中。

最近我们在Windows 10下使用Windows.Devices.Geolocation-API中的Geolocator发现了gps-module的一些问题(但以前在Windows 8.1上运行没有问题),没有提供任何位置。进一步调查和RTFM出现了 - 在Windows 10下 - 我们不得不在调用该位置之前调用RequestAccessAsync。

由于RequestAcessAsync-method在Windows 8.1中不可用,我们决定创建一个新的程序集,以Windows 10为目标(然后通过我们的配置轻松绑定/使用),效果非常好:

public Win10GpsProvider()
{
    RequestAccessAsync();
}

public async void RequestAccessAsnyc()
{
    //next line causes exception:
    var request = await Geolocator.RequestAccessAsync();
    switch (request)
    {
        // we don't even get here... :(
    }
}

只有在调用RequestAccessAsync方法时(在UI线程中)才会遇到抛出的异常,说明必须在应用程序容器的上下文中进行调用。

  

此操作仅在应用容器的上下文中有效。 (HRESULT异常:0x8007109A)

桌面和平板电脑都有异常(通过远程调试验证)。

再搜索一下,将“location”作为必需功能添加到package.appxmanifest可能有所帮助:

<Capabilities>
    <Capability Name="location"/>
</Capabilities>

这就是我们现在实际陷入困境的地方:

  • 我们没有UWP应用程序(并且实际上不希望/可以更改它,因为我们的目标是Win 8.1,并且已经定义了部署工作流程,包括设置)
  • 由于没有UWP app / context
  • ,我们无法毫无例外地获得程序集运行

有没有办法获得一个针对Windows 10版本的Windows.Devices.Geolocation-API的单独程序集,并且可以由Win32应用程序调用/加载?

1 个答案:

答案 0 :(得分:0)

AFAIK,无法调用RequestAcessAsync方法并使其在Windows 8.1应用中运行。

但是如果您在Windows 8.1项目中直接使用Geoposition,并在Windows 10设备上运行此Windows 8.1应用程序,例如在桌面上,则还会显示权限请求对话框:

enter image description here

因此,如果您不在Windows 8.1应用程序中调用RequestAcessAsync方法,则应该没有问题。

但是如果用户在此权限请求对话框中选择“否”,我们可以捕获异常并启动设置页面以强制用户启用此应用程序的位置设置,例如:

private Geolocator _geolocator = null;
private uint _desireAccuracyInMetersValue = 0;

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    try
    {
        var _cts = new CancellationTokenSource();
        CancellationToken token = _cts.Token;
        _geolocator = new Geolocator { DesiredAccuracyInMeters = _desireAccuracyInMetersValue };
        Geoposition pos = await _geolocator.GetGeopositionAsync().AsTask(token);

        // Subscribe to PositionChanged event to get updated tracking positions
        _geolocator.PositionChanged += OnPositionChanged;

        // Subscribe to StatusChanged event to get updates of location status changes
        _geolocator.StatusChanged += OnStatusChanged;
    }
    catch (Exception ex)
    {
        await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"));
    }
}

Windows 8.1项目中的此代码在Windows 8.1设备和Windows 10设备上都能正常工作。我不太明白你的Win32应用程序在这里是什么?