在Windows 10上,如何在Win32应用程序中使用UWP地理位置API?

3
我们正在构建一个多平台(桌面和平板电脑)应用程序,针对Windows 8.1和10。由于我们处理空间数据,因此我们提供了使用设备GPS接收器的当前位置的可能性。为了允许轻松适应(硬件)环境,我们将GPS逻辑(包括API调用)放置在外部程序集中,根据配置进行加载。
最近我们发现了一些问题,使用Geolocator从Windows.Devices.Geolocation-API的gps模块在Windows 10下(但以前在Windows 8.1上运行良好),未提供任何位置信息。进一步调查和RTFM显示,在Windows 10下,我们必须在调用位置之前调用RequestAccessAsync。
由于RequestAcessAsync方法在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... :(
    }
}

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

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

这个异常在桌面和平板电脑上都会发生(通过远程调试验证)。

进一步搜索,将“location”添加为package.appxmanifest所需的功能可能会有所帮助:

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

这就是我们目前卡住的地方:
  • 我们没有UWP应用程序(实际上不想/不能改变,因为我们同时针对Win 8.1并有一个定义的部署工作流包括设置)
  • 由于没有UWP应用程序/上下文,我们无法使程序集正常运行而不出现异常
有没有办法获取一个独立的程序集,它针对Windows.Devices.Geolocation-API的Windows 10版本,并且可以被Win32应用程序调用/加载?

你最终找到了可以分享的解决方案吗?我们在尝试从System.Device.Location切换到Windows.Devices.Geolocation时遇到了相同的问题,这是升级到.NET 6从4.8的一部分,但仅在某些Windows 10设备上。 - Aaron0
1个回答

0
据我所知,在Windows 8.1应用程序中调用RequestAcessAsync方法并使其正常工作是不可行的。
但是,如果您直接在Windows 8.1项目中使用Geoposition,并在Windows 10设备上运行此Windows 8.1应用程序,例如在桌面上运行,权限请求对话框也将显示出来:

enter image description here

如果在 Windows 8.1 应用程序中不调用 RequestAccessAsync 方法,则不应出现问题。

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

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应用程序在这里是做什么的?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接