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,這裡是我的開發筆記的網誌,如果你對我的文章有任何疑問或者有錯誤的話,歡迎留言讓我知道。