c# - 在 Windows 10 上将 UWP Geolocation-API 与 Win32-Application 结合使用

标签 c# .net winapi windows-10 uwp

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

最近,我们发现在 Windows 10 下使用来自 Windows.Devices.Geolocation-API 的地理定位器的 gps 模块存在一些问题(但之前在 Windows 8.1 上运行没有问题),无法提供任何位置信息。进一步调查和RTFM出现了,在 Windows 10 下,我们必须在调用位置之前调用 RequestAccessAsync。

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

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 线程中)时立即抛出,说明调用必须在应用程序容器的上下文中进行。

This operation is only valid in the context of an app container. (Exception from HRESULT: 0x8007109A)

异常发生在台式机和平板电脑上(通过远程调试验证)。

多搜索一点,将“位置”作为必需的功能添加到 package.appxmanifest 可能会有所帮助:

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

这就是我们目前真正陷入困境的地方:

  • 我们没有 UWP 应用程序(实际上不想/不能更改它,因为我们也以 Win 8.1 为目标并且有定义的部署工作流程,包括设置)
  • 我们无法让程序集无一异常(exception)地运行,因为没有 UWP 应用程序/上下文

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

最佳答案

据我所知,调用 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 应用程序在这里是什么?

关于c# - 在 Windows 10 上将 UWP Geolocation-API 与 Win32-Application 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39039797/

相关文章:

c# - string.IsNullOrEmpty(string)' 有一些无效参数

c# - 在哪个版本的 C# 索引器中引入了?

c# - 从控制台读取值

.net - 带有 bitbucket 管道的 Msbuild

c# - Sharepoint 和 .Net 开发的区别?

c++ - 当主 GUI 线程被阻塞时,如何从工作线程创建无模式对话框?

c# - 使用哪个 WM_Message?

c# - 如何在 C# 中获取另一个节点值指定的节点值

.net - HTTP 压缩 - 我可以配置客户端来压缩发送到服务器的数据吗?

c++ - 如何获得 Windows 线程的返回值?