Windows Phone 7 取得GPS訊號
要取得GPS的訊號主要是透過GeoCoordinateWatche來取得,下面的範例是一個簡單的取得經緯度的語法。
以上這種方式呼叫一次只會取得一次並不會繼續監聽GPS的訊號,但是如果我們是要寫GPS定位程式這樣的結果就不是我們想要的,我們需要的是能自動判斷GPS的訊號是否有改變。因此我們需要使用下面的方式來進行。建議使用低精準度(因愈高精準度需要更多的電力來收集資料)、低耗電與電力最佳化的目標,詳細說明可參閱MSDN。
上面的圖示所顯示的經緯度是在模擬器上面執行的,但是我發現該經緯度並不是我目前所在的位置,直覺告訴我應該是跟Andorid和iPhone一樣,模擬器無法找到正確的座標資訊,Google了一下,找到了模擬器的測試方式,如欲知詳情請參閱MSDN,以下語法就說明一下根據MSDN調整的方式。
1. 在Visual Studio的專案加入以下三個參考,"System.Device", "Microsoft.Phone.Reactive", "System.Observable"。
2. 在程式開頭加入以下語法
using System.Device.Location;
using Microsoft.Phone.Reactive;
using System.Threading;
下圖就是完成的樣子,理論上用Debug Mode來看GoogleMap就會一直往東北方移動。
GeoCoordinateWatcher geowatcher = new GeoCoordinateWatcher();
//嘗試取得資料,若超過指定的時間取不到就會回傳False
geowatcher.TryStart(false, TimeSpan.FromMilliseconds(1000));
GeoCoordinate coord = geowatcher.Position.Location;
if (coord.IsUnknown != true)
{
MessageBox.Show(
"Latitude : " + coord.Latitude.ToString() + Environment.NewLine +
"Longitude : " + coord.Longitude.ToString()
);
}
以上這種方式呼叫一次只會取得一次並不會繼續監聽GPS的訊號,但是如果我們是要寫GPS定位程式這樣的結果就不是我們想要的,我們需要的是能自動判斷GPS的訊號是否有改變。因此我們需要使用下面的方式來進行。建議使用低精準度(因愈高精準度需要更多的電力來收集資料)、低耗電與電力最佳化的目標,詳細說明可參閱MSDN。
// Current status of the location service GeoPositionStatus currentState = GeoPositionStatus.Initializing; // Use this class to access Windows Phone location service GeoCoordinateWatcher geoWatcher; // Current geo-location private GeoPositioncurrentGeoCoord = null; GeoPosition CurrentGeoCoord { get { return currentGeoCoord; } set { currentGeoCoord = value; } } // 建構函式 public MainPage() { geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default); geoWatcher.StatusChanged += new EventHandler (geoWatcher_StatusChanged); geoWatcher.PositionChanged += new EventHandler >(geoWatcher_PositionChanged); geoWatcher.MovementThreshold = 0.5; geoWatcher.Start(); } //位置服務狀態變更時 void geoWatcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e) { currentState = e.Status; switch (e.Status) { case GeoPositionStatus.Disabled: if (geoWatcher.Permission == GeoPositionPermission.Denied) { MessageBox.Show("Please turn on geo-location service in the settings tab."); } else if (geoWatcher.Permission == GeoPositionPermission.Granted) { MessageBox.Show("Your device doesn't support geo-location service."); } break; case GeoPositionStatus.Ready: CurrentGeoCoord = geoWatcher.Position; break; } } //位置服務偵測到位置改變時 void geoWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs e) { if (currentState == GeoPositionStatus.Ready) { CurrentGeoCoord = e.Position; } }
上面的圖示所顯示的經緯度是在模擬器上面執行的,但是我發現該經緯度並不是我目前所在的位置,直覺告訴我應該是跟Andorid和iPhone一樣,模擬器無法找到正確的座標資訊,Google了一下,找到了模擬器的測試方式,如欲知詳情請參閱MSDN,以下語法就說明一下根據MSDN調整的方式。
1. 在Visual Studio的專案加入以下三個參考,"System.Device", "Microsoft.Phone.Reactive", "System.Observable"。
2. 在程式開頭加入以下語法
using System.Device.Location;
using Microsoft.Phone.Reactive;
using System.Threading;
//Debug Mode
#if (DEBUG)
bool useEmulation = true;
#else
bool useEmulation = false;
#endif
// 建構函式
public MainPage()
{
//使用Debug Mode
if (!useEmulation)
{
geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
geoWatcher.StatusChanged += new EventHandler(geoWatcher_StatusChanged);
geoWatcher.PositionChanged += new EventHandler>(geoWatcher_PositionChanged);
geoWatcher.MovementThreshold = 0.5;
geoWatcher.Start();
}
else
{
// Start the thread on which emulated location data is generated.
// The method StartEmulation is defined next.
Thread emulationThread = new Thread(StartEmulation);
emulationThread.Start();
}
}
private void StartEmulation()
{
// EmulatePositionChangedEvents returns an IEnumerable object.
// Convert this to an Observable sequence.
var position = EmulatePositionChangedEvents().ToObservable();
// Subscribe to the Observable sequence.
// Use null for the sender parameter to the event handler.
position.Subscribe(evt => geoWatcher_PositionChanged(null, evt));
}
static double _latitude = 22.607090306469686;
static double _longitude = 120.3134036064148;
static IEnumerable> EmulatePositionChangedEvents()
{
// Create a Random object to create random numbers.
Random random = new Random();
// Loop infinitely.
for (; ; )
{
// Pause for 100 milliseconds in each loop.
Thread.Sleep(random.Next(100));
_latitude += 0.0001;
_longitude += 0.0001;
// Use yield to return a new instance of the GeoPositionChangedEventArgs class that is exposed
// through the IEnumerable interface.
yield return new GeoPositionChangedEventArgs(
new GeoPosition(DateTimeOffset.Now, new GeoCoordinate(_latitude, _longitude)));
}
}
下圖就是完成的樣子,理論上用Debug Mode來看GoogleMap就會一直往東北方移動。


留言
張貼留言
您好,我是 Lawrence,這裡是我的開發筆記的網誌,如果你對我的文章有任何疑問或者有錯誤的話,歡迎留言讓我知道。