65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Phone 8 上的地理定位服务。

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2014年8月22日

CPOL

7分钟阅读

viewsIcon

11774

地理定位是移动应用及其他领域中最常用的功能之一,通过它我们可以获取我们所在位置的地理信息。

引言

地理定位是移动应用及其他领域中最常用的功能之一,通过它我们可以获取我们所在位置的地理信息,并且可以通过应用程序查找附近的餐厅、酒店、景点等信息,以及许多其他场景。在 Windows Phone 8 操作系统中,地理定位主要依赖于三种工具。

  • GPS
  • 3G
  • Wi-Fi

GPS 毫无疑问是最精确的仪器,但缺点是耗电量大,且需要户外环境才能获得更准确的数据。3G 网络基于宽带连接,使用 UMTS 连接,允许上网浏览,耗电量确实比 GPS 小,但反过来精度也差了很多。最后是 Wi-Fi,它基于与设备连接的路由器进行连接,耗电量适中,精度也很好。

简要介绍了地理定位所依赖的工具后,我们来看看如何在 Windows Phone 8 应用程序中使用它。

Geolocator 类

Windows Runtime 为我们开发者提供了 Geolocator 类,它位于 Windows.Devices.Geolocation 命名空间中。这个类有多个属性、方法和事件,我们可以通过它们获取所有必需的位置数据。

它有五个属性

  • DesiredAccuracy
  • DesiredAccuracyInMeters
  • LocationStatus
  • MovementThreshold
  • ReportInterval

最常用的方法

  • GetPositionAsync ()

最后是两个事件

  • PositionChanged
  • StatusChanged

属性

DesiredAccuracy 属性允许您设置检测位置的精度级别。此属性可以是以下枚举值之一:PositionAccuracy

  • Default,接收数据的方式旨在确保正常的电池消耗和位置更新。
  • Hight,如果我们要更精确地接收位置数据,但请注意,设置此值将导致电池消耗增加,因此只有当您想实现的应用程序需要更高的数据精度时才应设置它。

DesiredAccuracyInMeters,获取或设置地理定位服务返回数据的所需精度(以米为单位)。LocationStatus,确定 GPS 信号的状态,可以是以下枚举值之一:PositionStatus

  • Disabled,手机上的地理定位服务已禁用,请记住,地理定位服务也可以由用户禁用。
  • Initializing,地理定位服务初始化阶段,此时位置数据可能尚不可用。
  • NotAvailable,地理定位服务不可用,但由于 Windows Phone 始终提供 GPS 服务,即使在低速下,此属性也永远不会取此值。
  • NoData,地理定位服务已激活,但目前无法检索数据,例如当连接性很差或没有连接时会发生这种情况。
  • NotInitialized,地理定位服务已激活,但目前尚未请求数据恢复,尚未执行 GetPositionAsync() 方法。
  • Ready,地理定位服务已激活,并准备好检索位置数据。

MovementThreshold,表示以米为单位的位置值,必须基于前一个位置进行测量。ReportInterval,表示两次位置读取之间应经过的最短时间(以毫秒为单位)。

方法

GetPositionAsync() 方法,它返回一个 Geoposition 类型的对象,我们可以在其中找到所有位置信息,例如坐标,其中包含纬度和经度值。这些值是最主要的用途,它还公开了一个 CivicAddress 属性,该属性又返回其他值,例如城市、国家/地区、邮政编码、省份。

事件

StatusChanged 事件在 GPS 信号状态更改时执行,因此有助于管理位置信息的下载,以便在连接性低或没有连接时向用户发出警告。此事件使用一个名为 Status 的值(Position Status 类型)返回连接信息,返回值与 LocationStatus 属性中描述的值相同。

PositionChanged 事件在找到新位置时执行,这一切都通过上面描述的 MovementThreshold 属性和 ReportInterval 的增强来实现。信息可以通过事件返回的 Position Coordinates 类型找到。我们还有 CivicAddress 属性,尽管尚未实现,但数据可能不准确,尤其是精确性。

使用 Windows Phone 8 获取位置

到目前为止,我们对地理定位服务进行了简要概述,要更深入地研究该主题,请参考官方文档 MSDN 库

让我们看看如何使用这些服务来检索纬度和经度值。启动 Visual Studio 2013(本示例使用专业版),然后创建一个新的空应用程序项目(Silverlight for Windows Phone),如图所示,并将其命名为 GeoPositionSample。

点击“确定”按钮确认,在下一个屏幕上,我们将选择一个 Windows Phone 8.0 应用程序。

我们点击“确定”确认,并等待解决方案完成。以下是初始项目的样子。

在图像的左侧是图形界面,我们可以在其中从工具箱插入控件,或使用 XAML,它将显示我们应用程序的预览。右侧是 XAML 代码 GUI。由于这是一个空应用程序,除了“application”和“page name”出现的部分外,我们没有其他控件。

为了显示纬度和经度数据,我们将在网格控件 ContentPanel 中放入四个 TextBlock 控件和一个 Button。首先,我们定义 XAML 代码,在名为 ContentPanel 的网格控件中创建四行两列,我们将在其中放置所有界面内容。

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="Auto"/>                
            </Grid.ColumnDefinitions>
            
            
            <TextBlock Grid.Row="0" Grid.Column="0" x:Name="tbkLatitude" Text="Latitude"/>
            <TextBlock Grid.Row="1" Grid.Column="0" x:Name="tbkLongitude" Text="Longitude"/>
            <TextBlock Grid.Row="0" Grid.Column="2" x:Name="tbkLatitudeValue"/>
            <TextBlock Grid.Row="1" Grid.Column="2" x:Name="tbkLongitudeValue"/>
            
            <Button Grid.Row="3" Grid.ColumnSpan="3" x:Name="btnFindCoordinate" Content="Find data" Tap="btnFindCoordinate_Tap"/>                        
        </Grid>

您会注意到已为 Button 控件创建了 Tap 事件,我们将在此处放置使我们的应用程序能够与地理定位服务交互所需的代码。更改名为 Titlepanel 的 StackPanel 控件中 TextBlock 控件的 Text 属性值,如图所示。

   <!--TitlePanel contiene il nome dell'applicazione e il titolo della pagina-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="Geolocation Sample" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
            <TextBlock Text="Main page" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>/

编写上述代码后,屏幕将呈现此外观。

创建了必要的控件后,我们来看一下这段代码需要什么来检索这些值。编辑代码文件,按 F7 键,或在解决方案资源管理器中展开 mainpage.XAML 文件,直到找到 MainPage.xaml.cs 文件(在我们的例子中是 XAML 文件,或者如果您使用 Vb.Net 开发)。单击鼠标即可进入代码隐藏文件。前面我们提到 Windows Runtime 为我们提供了 Geolocator,所以第一件事是在文件中添加命名空间代码。

using Windows.Devices.Geolocation;

转到 Tap 事件,并在其中写入以下代码。

 var locator = new Geolocator();
 
 
            if (!locator.LocationStatus.Equals(PositionStatus.Disabled))
            {
                var position = await locator.GetGeopositionAsync();
                tbkLatitudeValue.Text = position.Coordinate.Latitude.ToString();
                tbkLongitudeValue.Text = position.Coordinate.Longitude.ToString();
            }
 
            else
            {
                MessageBox.Show("Service Geolocation not enabled!", AppResources.ApplicationTitle, MessageBoxButton.OK);
                return;
            }

它是如何工作的?声明一个名为 locator 的变量,建议使用 Geolocator 检查状态以验证服务是否激活,否则我们在尝试检测位置时会收到异常。这通过检查 LocationStatus 的值是否为“Disabled”来完成。

如果服务已启用,它将运行 GetPositionAsync() 方法,该方法返回所有位置数据。应注意的是,此方法是异步的,这意味着应用程序在下载数据之前不会被阻塞,但用户可以继续与 UI 控件进行交互。但是,本文不讨论异步编程,有关更全面详细的信息,我将提供文档链接 MSDN

GetPositionAsync() 方法执行时,我们将 tbkLatitudeValuetbkLongitudeValue TextBlock 控件用 GeoCoordinate 类型的 Latitude 和 Longitude 属性值进行增强,然后使用 ToString() 转换为字符串,因为它的类型是 double。我们放在 Button 的 Tap 事件中的代码如下定义:

        private async void btnFindCoordinate_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            var locator = new Geolocator();
 
 
            if (!locator.LocationStatus.Equals(PositionStatus.Disabled))
            {
                var position = await locator.GetGeopositionAsync();
                tbkLatitudeValue.Text = position.Coordinate.Latitude.ToString();
                tbkLongitudeValue.Text = position.Coordinate.Longitude.ToString();
            }
 
            else
            {
                MessageBox.Show("Service Geolocation not enabled!", AppResources.ApplicationTitle, MessageBoxButton.OK);
                return;
            }
        }

在继续应用程序之前,调试时必须启用 ID_CAP_LOCATION 功能,否则应用程序将无法工作。在解决方案资源管理器中,展开 Properties 文件夹,然后单击 WMAppManifest.xml 文件,如图所示。

打开文件,转到功能选项卡,然后选择该功能。

完成此操作后,我们可以继续调试应用程序。重要的是,如果您使用的是模拟器,DesiredAccuracy 属性必须设置为 High,才能检测位置变化。如果一切就绪,我们的主屏幕将呈现此外观。

点击按钮,我们就会看到纬度经度数据,正如预期的那样。

结论

在这第一篇文章中,我们看到了如何通过纬度和经度获取位置。在未来的文章中,我们将探讨如何获取 Geolocator 暴露的其他信息,然后将其用于我们的应用程序,以及如何通过纬度和经度使用 ReverseGeocodeQuery 类获取其他信息。可用的工作方法有很多,我们将逐一探索。

© . All rights reserved.