2013-01-18 29 views
0

我的應用的一些用戶抱怨跟蹤方不起作用。當應用程序啓動GeoCoordinateWatcher並試圖獲取當前位置時,屏幕頂部有一個GPS圖標閃爍。完成並確定後,圖標停止閃爍並顯示Ready(就緒)信息。用戶報告發生這種情況,但屏幕上的項目(如速度)永不更新。當應用程序保存它所跟蹤的位置時,沒有任何內容。在Windows Phone應用中的位置跟蹤問題

這裏是跟蹤部分的代碼。在頁面加載事件中,它會調用以下內容

/// <summary> 
    /// Starts tracking the user 
    /// </summary> 
    private void StartTracking() 
    { 
     var app = (Application.Current as App); 

     // check to see if tracking is enabled by the user      
     if (app.LocationTrackingIsEnabled) 
     {    
       (new Thread(() => 
       { 
        // Create the GeoWatcher 
        var watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High) { MovementThreshold = 1 }; 

        // Check to see if we have permission to use the location services of the phone 
        if (watcher.Permission == GeoPositionPermission.Granted) 
        { 
         watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged); 

         var status = Observable.FromEvent<GeoPositionStatusChangedEventArgs>(watcher, "StatusChanged"); 
         var readys = status.Where(o => o.EventArgs.Status == GeoPositionStatus.Ready); 
         var notReadys = status.Where(o => o.EventArgs.Status != GeoPositionStatus.Ready); 
         var readyPos = from r in readys 
             from i in Observable.Interval(TimeSpan.FromSeconds(LocationTrackInterval)) 
             .TakeUntil(notReadys) 
             where (DateTime.Now - watcher.Position.Timestamp.DateTime) < TimeSpan.FromSeconds(12) 
             select watcher.Position; 

         LocationSubscribe = readyPos.Subscribe(loc => 
         { 
          if (!HasPaused) 
          { 
           this.Dispatcher.BeginInvoke(new Action(() => 
           { 
            // Get current speed (meters per second); 
            if (!double.IsNaN(loc.Location.Speed)) 
             app.CurrentPos.CurrentSpeed = Math.Round(loc.Location.Speed, 2); 
            else 
             app.CurrentPos.CurrentSpeed = 0; 

            // Calculate distance 
            if (RunLocations.Count > 0) 
             app.CurrentPos.DistanceMeters += Math.Round(new GeoCoordinate(RunLocations[RunLocations.Count - 1].Latitude, 
              GPSLocations[GPSLocations.Count - 1].Longitude).GetDistanceTo(loc.Location), 2); 

            // Add Location 
            GPSLocations.Add(new GPSLocation() 
            { 
             Latitude = loc.Location.Latitude, 
             Longitude = loc.Location.Longitude, 
             Altitude = loc.Location.Altitude, 
             Speed = app.CurrentRun.CurrentSpeed 
            }); 

            // Get the average speed 
            app.CurrentPos.AverageSpeed = Math.Round((from r in GPSLocations 
                       select r.Speed).Average(), 2); 


            // Set last position for use later 
            Lastlocation = loc.Location; 
           })); 
          } 
         }); 

         // Try and start the watcher 
         if (!watcher.TryStart(false, TimeSpan.FromSeconds(5))) 
         { 
          this.Dispatcher.BeginInvoke(new Action(() => 
          { 
           MessageBox.Show("There was an error trying to get your location. Tracking is not possible."); 
          })); 
         } 
        } 
        else 
        { 
         sbGpsFlash.Stop(); // stop the flashing gps symbol 
         gpsStatus.Text = "Denied"; 
        } 

       })).Start();     
     } 
     else 
     { 
      sbGpsFlash.Stop(); // stop the flashing gps symbol 
      gpsStatus.Text = "Disabled"; 
     } 
    } 

void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e) 
    { 
     this.Dispatcher.BeginInvoke(new Action(() => 
     { 
      gpsStatus.Text = e.Status.ToString(); 

      switch (e.Status) 
      { 
       case GeoPositionStatus.Initializing: 
        gpsStatus.Text = "Locating..."; 
        break; 
       case GeoPositionStatus.Disabled: 
        gpsStatus.Text = "Disabled"; 
        break; 
       case GeoPositionStatus.NoData: 
        gpsStatus.Text = "No Data"; 
        break; 
       case GeoPositionStatus.Ready: 
        gpsStatus.Text = "Ready"; 
        break;          
      } 

      sbGpsFlash.Stop(); 
     })); 
    } 

任何人都可以看到可能導致問題的代碼問題嗎?

回答

0

在主線上創建您的geocoordinatewatcher

+0

因此將觀察者=新的GeoCoordinateWatcher(GeoPositionAccuracy.High)移動到主線程上。我可以問爲什麼?只是爲了我的理解:-) – Gaz83

+0

只是一個預感。如果在主線程之外的線程上創建GCW,它將擁有不同的調度程序,並且會出現各種跨線程訪問問題。基本上,你正在創造完全相反的情況,在這種情況下,工作線程無法觸及主線程創建的窗口小部件。另外,當我嘗試使用GCW時,我在主線程中創建了它,並沒有遇到任何麻煩。 –

0

只是一面評論。

您的代碼非常緊湊,但不易讀。

您不必在主線程上創建座標觀察器。

我想知道你只是對狀態事件進行了subsribe,而對位置瑣事沒有幫助,但這是你的邏輯,如果對你來說很好,那就好了。

Point是你想要顯示在UI上的數據只能被分配給創建UI控件的線程中的UI控件,通常這是一個線程人們稱之爲「主」線程。我不知道爲什麼這是主線。實際上我會稱它爲一個UI線程。

因此,您必須在創建UI控件的UI線程中傳遞數據。 因此,請在UI線程上啓動觀察器,或者使用UI線程的分派器將數據傳遞給它並將數據分配給UI控件。