2012-05-14 65 views
5

我正在嘗試檢索GPS修復中使用的衛星數。我已經實現了兩個不同的方法,如下圖所示:從Android獲取gps修復中使用的衛星數#

package ti.utils; 

import android.app.Activity; 
import android.content.Context; 
import android.location.GpsSatellite; 
import android.location.GpsStatus; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 

public class Gps { 

    private static final int TWO_MINUTES = 1000 * 60 * 2; 
    private static Location Location; 
    public static int Satellites = -1; 

    public static void StartTracking(Activity activity) 
    { 
     final LocationManager locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE); 

     //listen for gps status changes. 
     GpsStatus.Listener gpsStatusListener = new GpsStatus.Listener() { 
      public void onGpsStatusChanged(int event) { 
       Log("In onGpsStatusChanged event: " + event); 
       if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS || event == GpsStatus.GPS_EVENT_FIRST_FIX) { 
        GpsStatus status = locationManager.getGpsStatus(null); 
        Iterable<GpsSatellite> sats = status.getSatellites(); 
        // Check number of satellites in list to determine fix state 
        Satellites = 0; 
        for (GpsSatellite sat : sats) { 
         //if(sat.usedInFix()) 
         Satellites++; 
        } 
        Log("Setting Satellites from GpsStatusListener: " + Satellites); 
       } 
      } 
     }; 
     locationManager.addGpsStatusListener(gpsStatusListener); 

     //listen for location changes. 
     LocationListener locationListener = new LocationListener() { 
      public void onLocationChanged(Location location) { 
       // Called when a new location is found by the network location provider. 
       try 
       { 
        Log("Location changed! Speed = " + location.getSpeed() + " & Satellites = " + location.getExtras().getInt("satellites")); 
        boolean isBetter = isBetterLocation(location, Location); 
        if(isBetter) 
        { 
         Log("Set to new location"); 
         Location = location; 
         Satellites = location.getExtras().getInt("satellites"); 
         Log("Setting Satellites from LocationListener: " + Satellites); 
        } 
       } 
       catch(Exception exc) 
       { 
        Log(exc.getMessage()); 
       } 
      } 
      public void onStatusChanged(String provider, int status, Bundle extras) {} 
      public void onProviderEnabled(String provider) {} 
      public void onProviderDisabled(String provider) {} 
     }; 
     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 
    } 

    /** Determines whether one Location reading is better than the current Location fix 
     * @param location The new Location that you want to evaluate 
     * @param currentBestLocation The current Location fix, to which you want to compare the new one 
     */ 
    protected static boolean isBetterLocation(Location location, Location currentBestLocation) { 
     if (currentBestLocation == null) { 
      // A new location is always better than no location 
      return true; 
     } 

     // Check whether the new location fix is newer or older 
     long timeDelta = location.getTime() - currentBestLocation.getTime(); 
     boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; 
     boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; 
     boolean isNewer = timeDelta > 0; 

     // If it's been more than two minutes since the current location, use the new location 
     // because the user has likely moved 
     if (isSignificantlyNewer) { 
      return true; 
     // If the new location is more than two minutes older, it must be worse 
     } else if (isSignificantlyOlder) { 
      return false; 
     } 

     // Check whether the new location fix is more or less accurate 
     int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); 
     boolean isLessAccurate = accuracyDelta > 0; 
     boolean isMoreAccurate = accuracyDelta < 0; 
     boolean isSignificantlyLessAccurate = accuracyDelta > 200; 

     // Check if the old and new location are from the same provider 
     boolean isFromSameProvider = isSameProvider(location.getProvider(), 
       currentBestLocation.getProvider()); 

     // Determine location quality using a combination of timeliness and accuracy 
     if (isMoreAccurate) { 
      return true; 
     } else if (isNewer && !isLessAccurate) { 
      return true; 
     } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 
      return true; 
     } 
     return false; 
    } 

    /** Checks whether two providers are the same */ 
    private static boolean isSameProvider(String provider1, String provider2) { 
     if (provider1 == null) { 
      return provider2 == null; 
     } 
     return provider1.equals(provider2); 
    } 

    private static void Log(String message) { 
     if(message != null && message.length() > 0) { 
      //android.util.Log.i(LCAT, message); 
      org.appcelerator.kroll.common.Log.i("SygicModule", message); 
     } 
    } 

} 

無論聽者事件(onGpsStatusChanged & onLocationChanged)曾經火,即使我有我的手機上啓用了獨立的GPS。我有ACCESS_FINE_LOCATION權限集:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 

我下載了所謂的GPS地位的第三方應用程序,它是能夠正確顯示的衛星#,所以我知道這是不是我的Droid X2的問題。

任何想法?

回答

3
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 

應該

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 
+0

這有助於第二種方法,現在onLocationChanged事件被解僱,但它總是有0顆衛星在location.getExtras()。getInt(「satellites」) – Justin

+0

這結束了工作......我以爲我是嘗試兩種單獨的方法,但事實證明,我需要兩個工作! – Justin

+0

很高興你的工作;) – techiServices

0

如果你不能得到衛星通過GPS_EVENT_SATELLITE_STATUS的numebr那麼你可以 有你的活動實施NmeaListener

如果你實現NmeaListener,那麼你將不得不解析在onNmeaReceived中收到的消息字符串,以便提取衛星的數量。 NMEA格式描述爲here。然後,你可能想要做一個谷歌搜索「Java」+「NMEA分析器」

+0

我覺得很難相信我必須手動解析通過NMEA數據只是爲了檢索衛星#。第一種方法還處理GPS_EVENT_FIRST_FIX事件,這應該被解僱。另外,你沒有提到第二種方法,它應該在位置改變時被解僱... – Justin

+0

嗯,我相當肯定當我的手機運行薑餅時,它總是返回0顆衛星。現在它正在運行的ICS I可以看到GPS_EVENT_SATELLITE_STATUS中的衛星數量。我會編輯我的答案。 – NickT

+0

我的索尼愛立信Xperia Pro運行Gingerbread 2.3.4也返回0顆衛星。解析NMEA數據並沒有幫助(也是0質量),並且基於http://stackoverflow.com/questions/587441/roll-your-own-nmea-parser-or-use-an-open-source- gps解析器似乎NMEA是不可靠的,我將不得不去尋找GPS設備的特定二進制格式。 – Piovezan

6

這是最終工作的代碼。

package ti.utils; 

import android.app.Activity; 
import android.content.Context; 
import android.location.GpsSatellite; 
import android.location.GpsStatus; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 

public class Gps { 

    private static final int TWO_MINUTES = 1000 * 60 * 2; 
    private static Location Location; 
    public static int Satellites = -1; 

    public static void StartTracking(Activity activity) 
    { 
     final LocationManager locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE); 

     //listen for gps status changes. 
     GpsStatus.Listener gpsStatusListener = new GpsStatus.Listener() { 
      @Override 
      public void onGpsStatusChanged(int event) { 
       Log("In onGpsStatusChanged event: " + event); 
       if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS || event == GpsStatus.GPS_EVENT_FIRST_FIX) { 
        GpsStatus status = locationManager.getGpsStatus(null); 
        Iterable<GpsSatellite> sats = status.getSatellites(); 
        // Check number of satellites in list to determine fix state 
        Satellites = 0; 
        for (GpsSatellite sat : sats) { 
         //if(sat.usedInFix()) 
         Satellites++; 
        } 
        Log("Setting Satellites from GpsStatusListener: " + Satellites); 
       } 
      } 
     }; 
     locationManager.addGpsStatusListener(gpsStatusListener); 

     //listen for location changes. 
     LocationListener locationListener = new LocationListener() { 
      @Override 
      public void onLocationChanged(Location location) { 
       // Called when a new location is found by the network location provider. 
       /*try 
       { 
        Log("Location changed! Speed = " + location.getSpeed() + " & Satellites = " + location.getExtras().getInt("satellites")); 
        boolean isBetter = isBetterLocation(location, Location); 
        if(isBetter) 
        { 
         Log("Set to new location"); 
         Location = location; 
         Satellites = location.getExtras().getInt("satellites"); 
         Log("Setting Satellites from LocationListener: " + Satellites); 
        } 
       } 
       catch(Exception exc) 
       { 
        Log(exc.getMessage()); 
       }*/ 
      } 
      public void onStatusChanged(String provider, int status, Bundle extras) {} 
      public void onProviderEnabled(String provider) {} 
      public void onProviderDisabled(String provider) {} 
     }; 
     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 
    } 

    /** Determines whether one Location reading is better than the current Location fix 
     * @param location The new Location that you want to evaluate 
     * @param currentBestLocation The current Location fix, to which you want to compare the new one 
     */ 
    protected static boolean isBetterLocation(Location location, Location currentBestLocation) { 
     if (currentBestLocation == null) { 
      // A new location is always better than no location 
      return true; 
     } 

     // Check whether the new location fix is newer or older 
     long timeDelta = location.getTime() - currentBestLocation.getTime(); 
     boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; 
     boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; 
     boolean isNewer = timeDelta > 0; 

     // If it's been more than two minutes since the current location, use the new location 
     // because the user has likely moved 
     if (isSignificantlyNewer) { 
      return true; 
     // If the new location is more than two minutes older, it must be worse 
     } else if (isSignificantlyOlder) { 
      return false; 
     } 

     // Check whether the new location fix is more or less accurate 
     int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); 
     boolean isLessAccurate = accuracyDelta > 0; 
     boolean isMoreAccurate = accuracyDelta < 0; 
     boolean isSignificantlyLessAccurate = accuracyDelta > 200; 

     // Check if the old and new location are from the same provider 
     boolean isFromSameProvider = isSameProvider(location.getProvider(), 
       currentBestLocation.getProvider()); 

     // Determine location quality using a combination of timeliness and accuracy 
     if (isMoreAccurate) { 
      return true; 
     } else if (isNewer && !isLessAccurate) { 
      return true; 
     } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 
      return true; 
     } 
     return false; 
    } 

    /** Checks whether two providers are the same */ 
    private static boolean isSameProvider(String provider1, String provider2) { 
     if (provider1 == null) { 
      return provider2 == null; 
     } 
     return provider1.equals(provider2); 
    } 

    private static void Log(String message) { 
     if(message != null && message.length() > 0) { 
      //android.util.Log.i(LCAT, message); 
      org.appcelerator.kroll.common.Log.i("UtilsModule", message); 
     } 
    } 

} 
+1

爲什麼你有'if(sat.usedInFix())'語句被註釋掉了?如果您希望您的計數屬於最近修復中實際使用的衛星,我會對該行取消註釋。 –

0

我在代碼中得到了它的工作。 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationUpdateHandler()); int nSatellites = location.getExtras().getInt("satellites", -1);

nSatellites被發現是> 0,一旦我開始修復(onLocationChanged回調)。

相關問題