地理位置服务(Location Service)【WP7学习札记之十五】
Microsoft 地理位置服務(wù)允許開發(fā)者為 Windows Phone 創(chuàng)建位置感知應(yīng)用程序。該服務(wù)從獲得來源(如 GPS、Wi-Fi 和蜂窩)獲取位置數(shù)據(jù)。它可以使用一個(gè)或多個(gè)來源推導(dǎo)出 Windows Phone 的位置,從而根據(jù)應(yīng)用程序的需要平衡性能和電能利用。通過事件驅(qū)動(dòng)的托管代碼接口向應(yīng)用程序公開位置。
◇定位服務(wù)體系結(jié)構(gòu):
第一層由 Windows Phone 設(shè)備中的硬件組成。這包括 GPS 接收器、Wi-Fi 和蜂窩收音機(jī)。這些可以全部充當(dāng)精度和能耗級(jí)別各不相同的位置數(shù)據(jù)的提供程序;
在硬件的上面是本機(jī)代碼層。該層直接與可用的位置數(shù)據(jù)來源通信并決定使用哪個(gè)來源,根據(jù)數(shù)據(jù)的可用性以及應(yīng)用程序指定的性能要求確定設(shè)備的位置。本機(jī)代碼層還借助 Microsoft 托管的 Web 服務(wù)與 Internet 通信,以從數(shù)據(jù)庫(kù)查找與位置有關(guān)的信息;
定位服務(wù)的頂層是托管接口,通過 Windows Phone SDK 附帶的 DLL 公開。應(yīng)用程序使用該接口啟動(dòng)和停止定位服務(wù),設(shè)置應(yīng)用程序所需的精度級(jí)別以及從本機(jī)代碼層(當(dāng)它變?yōu)榭捎脮r(shí))接收位置數(shù)據(jù)。
◇創(chuàng)建使用Location Service程序的最佳實(shí)踐:
創(chuàng)建位置感知應(yīng)用程序時(shí),開發(fā)人員必須平衡應(yīng)用程序的以下兩個(gè)要求:具有精確位置數(shù)據(jù);耗電量最小。在移動(dòng)設(shè)備上,這兩個(gè)應(yīng)用程序要求是反比關(guān)系。生成不太精確位置信息的硬件(如 Wi-Fi 和蜂窩收音機(jī))使用的電量要比 GPS 接收器(通常,可以獲得更精確的位置數(shù)據(jù))使用的電量小。設(shè)計(jì)應(yīng)用程序時(shí),要遵循兩個(gè)基本原則。
為位置數(shù)據(jù)選擇適當(dāng)?shù)木燃?jí)別:盡管定位服務(wù)使用多個(gè)位置信息來源,但是在任何給定的時(shí)間任何來源都可能會(huì)不可用(例如,無法訪問 GPS 衛(wèi)星或基站),本機(jī)代碼層負(fù)責(zé)計(jì)算可用數(shù)據(jù)并選擇最佳來源集。您的應(yīng)用程序所需要做的就是在高精度或默認(rèn)的電量?jī)?yōu)化設(shè)置之間進(jìn)行選擇。可以在初始化主定位服務(wù)類 GeoCoordinateWatcher 時(shí)設(shè)置該值。
GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
設(shè)置合理的移動(dòng)閾值:由于移動(dòng)設(shè)備中的 GPS 硬件沒有天線,因此傳感器通常設(shè)計(jì)為非常敏感。這種靈敏度可能會(huì)導(dǎo)致信號(hào)中有少量來自表面反射以及其他環(huán)境影響的噪音。主定位服務(wù)類 GeoCoordinateWatcher 顯示 MovementThreshold 屬性。該屬性指定在引發(fā) PositionChanged 事件之前必須進(jìn)行的位置方面的最小更改。如果您將 MovementThreshold 屬性設(shè)置為一個(gè)非常低的值,則可能會(huì)導(dǎo)致您的應(yīng)用程序接收實(shí)際上是由信號(hào)噪音所導(dǎo)致的事件。為了平滑信號(hào)以便僅表示位置中的重大更改,請(qǐng)將 MovementThreshold 屬性設(shè)置為至少 20 米。這也會(huì)使您應(yīng)用程序的耗電量降低。將移動(dòng)閾值設(shè)置為 0 米將導(dǎo)致頻繁引發(fā)事件,一秒鐘一個(gè)事件。該設(shè)置對(duì)于導(dǎo)航應(yīng)用程序可能非常有用。
下面給出一個(gè)例子演示如何從 Windows Phone 的定位服務(wù)獲取數(shù)據(jù):
MainPage.xaml代碼如下:
View Code
<phone:PhoneApplicationPage
x:Class="GeoPosition.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="演示程序" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="地理位置" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Height="30" HorizontalAlignment="Left" Margin="27,76,0,0" Name="textBlock1" Text="經(jīng)度" VerticalAlignment="Top" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="24,153,0,0" Name="textBlock2" Text="緯度" VerticalAlignment="Top" />
<TextBox Height="72" HorizontalAlignment="Left" Margin="70,50,0,0" Name="logTxtBox" Text="" VerticalAlignment="Top" Width="460" />
<TextBox Height="72" HorizontalAlignment="Left" Margin="70,128,0,0" Name="latTxtBox" Text="" VerticalAlignment="Top" Width="460" />
<Button Content="開始" Height="72" HorizontalAlignment="Left" Margin="70,299,0,0" Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" />
<Button Content="結(jié)束" Height="72" HorizontalAlignment="Left" Margin="248,299,0,0" Name="button2" VerticalAlignment="Top" Width="160" Click="button2_Click" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="24,230,0,0" Name="textBlock3" Text="狀態(tài)" VerticalAlignment="Top" />
<TextBox Height="72" HorizontalAlignment="Left" Margin="70,206,0,0" Name="statusTxtBox" Text="" VerticalAlignment="Top" Width="460" />
</Grid>
</Grid>
<!--Sample code showing usage of ApplicationBar-->
<!--<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="MenuItem 1"/>
<shell:ApplicationBarMenuItem Text="MenuItem 2"/>
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>-->
</phone:PhoneApplicationPage>
MainPage.xaml.cs代碼如下:
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
namespace GeoPosition
{
public partial class MainPage : PhoneApplicationPage
{
GeoCoordinateWatcher watcher;
// Constructor
public MainPage()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (watcher == null)
{
watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);// using high accuracy
watcher.MovementThreshold = 20;// use MovementThreshold to ignore noise in the signal
//為 StatusChanged 和 PositionChanged 事件添加事件處理程序
watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
//
watcher.Start();
}
}
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
//回調(diào),多線程操作
Dispatcher.BeginInvoke(() =>
{
logTxtBox.Text = e.Position.Location.Longitude.ToString("0.000");
latTxtBox.Text = e.Position.Location.Latitude.ToString("0.000");
});
}
void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.Disabled :
if (watcher.Permission == GeoPositionPermission.Denied)
{
// The user has disabled the Location Service on their device.
statusTxtBox.Text = "you have this application access to location.";
}
else
{
statusTxtBox.Text = "location is not functioning on this device";
}
break;
case GeoPositionStatus.Initializing :
// The Location Service is initializing.
// Disable the Start Location button.
break;
case GeoPositionStatus.NoData :
statusTxtBox.Text = "location data is not available.";
break;
case GeoPositionStatus.Ready:
statusTxtBox.Text = "location data is available";
break;
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
watcher.Stop();
}
}
}
(注意這個(gè)多線程操作~)
在模擬器上運(yùn)行效果如圖:
具體請(qǐng)參見MSDN:Windows Phone 的位置(http://msdn.microsoft.com/zh-cn/library/ff431803(v=vs.92).aspx)
總結(jié)
以上是生活随笔為你收集整理的地理位置服务(Location Service)【WP7学习札记之十五】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux C语言中sscanf 的详细
- 下一篇: Swift 阳历转农历,农历转公历