【问题标题】:How to support Windows 8 & 8.1 Geolocation API如何支持 Windows 8 和 8.1 Geolocation API
【发布时间】:2014-03-10 19:03:33
【问题描述】:

我已在我的程序中添加了地理定位支持,但我遇到了一个不知道如何处理的问题。我正在使用 VS 2012。

我在我的解决方案中添加了一个 DLL,它可以进行所有地理定位调用。我在 .csproj 文件中将支持的 Windows 版本设置为 8.1。 DLL 项目也使用 .NET 4.5,而解决方案中的其余项目使用 .NET 4.0。

我在检索位置的方法中有以下代码:

protected override void Initialize() {
    // Initialization code here

    ParseGeoposition();  // Exception is thrown on this line
}

private void ParseGeoPositin() { 
    // . . .

    bool done = false;
    while ( !done )
        try {
            if ( UseCoordinate ) {
                newPosition.Position.Latitude  = positionRecord.Coordinate.Latitude;
                newPosition.Position.Longitude = positionRecord.Coordinate.Longitude;
            } else {
                newPosition.Position.Latitude  = positionRecord.Coordinate.Point.Position.Latitude;
                newPosition.Position.Longitude = positionRecord.Coordinate.Point.Position.Longitude;
            }
            done = true;
        } catch ( MissingMethodException ) {
            if ( !UseCoordinate ) {
                throw new NotSupportedException( "This machine does not support the Windows Geolocation API." );
            }
            UseCoordinate = false;
        }
    // . . .
}

UseCoordinate 标志以 true 开头。代码应该切换到使用Point 属性(通过将UseCoordinate 设置为false 如果不支持Coordinate 属性。

代码在我的 Windows 8.1 开发机器上运行良好。但是,当我将它安装在 Windows 8.0 机器上时,A MissingMethodException 被抛出在调用包含此代码的方法的行上。就好像没有尝试一样。抛出的异常如下:

System.MissingMethodException:找不到方法:'Windows.Devices.Geolocation.Geopoint Windows.Devices.Geolocation.Geocoordinate.get_Point()'。

显然我的方法是有缺陷的。我不想查看 Windows 版本号,因为我的经理不希望我这样做。编写此代码的正确方法是什么

【问题讨论】:

  • 这是桌面应用程序,不是 Windows 商店应用程序

标签: c# .net windows-store-apps


【解决方案1】:

使用来自 Rowland 的信息,我能够完成这项工作。 Windows 8 和 Windows 8.1 API 之间的区别在于 Geocoordinate 类的 Coordinate 属性。在 Windows 8 中,Coordinate 属性是具有LatitudeLongitudeAltitude 属性的Geocoordinate 对象。在 Windows 8.1 中,这些属性仍然存在,但被标记为已过时。 Windows 8.1 中的Geocoordinate 类有一个名为Point 的新属性,类型为Geopoint。这有一个名为Position 的属性,类型为BasicGeoposition。此对象具有LatitudeLongitudeAltitude 属性。

在名为positionRecord的类中已经有一个私有实例变量:

private Geoposition positionRecord = null;

这是通过在Initialize 方法中调用GetPositionAsync 来设置的,然后每当Geolocator 引发其PositionChanged 事件时。我在代码中创建了两组函数:

private double GetAltitudeFromCoordinate() {
    return positionRecord.Coordinate.Altitude == null ? 0.0 : positionRecord.Coordinate.Altitude.Value;
}

private double GetAltitudeFromPoint() {
    return positionRecord.Coordinate.Point.Position.Altitude;
}

private double GetLatitudeFromCoordinate() {
    return positionRecord.Coordinate.Latitude;
}

private double GetLatitudeFromPoint() {
    return positionRecord.Coordinate.Point.Position.Latitude;
}

private double GetLongitudeFromCoordinate() {
    return positionRecord.Coordinate.Longitude;
}

private double GetLongitudeFromPoint() {
    return positionRecord.Coordinate.Point.Position.Longitude;
}

接下来,我创建了两个用于解析纬度和经度的方法:

private void ParseLatLonFromCoordinate( GpsInformation newPosition ) {
    // We assume this is a Windows 8.0 machine that doesn't have the Point property.
    newPosition.Position.Latitude  = positionRecord.Coordinate.Latitude;
    newPosition.Position.Longitude = positionRecord.Coordinate.Longitude;
}

private void ParseLatLonFromPoint( GpsInformation newPosition ) {
    // The system must not support the Coordinate.Latitude & Longitude properties any more.
    newPosition.Position.Latitude  = positionRecord.Coordinate.Point.Position.Latitude;
    newPosition.Position.Longitude = positionRecord.Coordinate.Point.Position.Longitude;
}

我在类中添加了一个名为 UseCoordinatesbool 属性。在程序的初始化代码中,我添加了这一行来初始化标志:

UseCoordinate = positionRecord.Coordinate.GetType().GetProperty( "Point" ) == null;

最后,我添加了一个名为ParsePosition 的方法,它在上述代码之后以及每当Geolocator 引发PositionChanged 事件时调用:

private void ParsePosition() {
    GpsInformation newPosition = new GpsInformation();
    newPosition.TimeStamp = DateTime.Now;

    try {
        if ( UseCoordinate )
            ParseLatLonFromCoordinate( newPosition );
        else
            ParseLatLonFromPoint( newPosition );
    } catch ( MissingMethodException ) {
        // The Geolocation API must not be supported.
        throw new NotSupportedException( "This machine does not support the Windows Geolocation API." );
    }

    // . . .
}

这适用于 Windows 8 和 8.1 而不会抛出 MissingMethodExceptions.

【讨论】:

    【解决方案2】:

    当 JITer 编译方法时发生异常 - 您需要使用 8.0 兼容的地理位置 API 调用(Geolocator 和朋友),或者保护对使用 8.1 特定指令的方法的调用适当的try ... catch 块。

    【讨论】:

    • 我给你的功劳,但我将添加另一个答案来概述我所做的事情。评论太长了。
    • 顺便说一句,GeoCoordinateWatcher 是 Windows 7 API,而不是 Windows 8.0 API。
    • 好点,我将复制粘贴我的抽象名称,而不是在 Windows 8.0(及更高版本)上工作的底层类,我现在添加了它,并带有文档链接
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-23
    • 2017-08-04
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多