Android學習筆記(五六:位置Location
建議更新20130522的ADT版本,無論是Linux下還是Windows下,我覺得速度快了很多。而且將Android SDK Tool升級到ver 22版本後,原來的ADT有很多不明原因問題,載入App到模擬器上出現連線不上的情況。
允許應用具備定位功能
Location是手機功能的一大特色,衛星導航除了GPS外,還有歐洲的伽利略和我國的北斗,此外還有運營商移動基站的三角定位、第三方提供WiFi熱點定位等方式。相關推薦可以閱讀CDMA的定位方式。利用基站訊號的強弱進行三角特定的方式(在市區內受到建築阻擋和反射等影響),利用上網的AP所出的地理位置來進行定位,都屬於粗定位coarse location,利用衛星的精確定位為fine location。應用要具備定位功能,首先必須進行許可權許可。
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
在模擬器中設定位置
我們可以通過DDMS在模擬器中設定經緯度,並在程式執行是修改經緯度。Window -> Open perspective -> DDMS
連續位置獲取小例子
下面的例子很簡單,UI是一個TextView用來顯示資訊。我們進行裝置位置的不斷跟蹤,也就是跟蹤我們的路徑。
public class LocationBase extends Activity{ private TextView myText; private String textStr = ""; private LocationManager mgr=null; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.pure_text_view); myText = (TextView) findViewById(R.id.pure_text); addText("Location Based-Services Demo...");
我們可能會發現一開始並沒有出發到位置監控器的onLocationChanged(),在實際中,可能由於GPS沒有開啟,或者剛開啟,不能馬上得到位置資訊。在模擬器中,我們在DDMS中將按“send”按鈕即可。更改位置資訊,同樣需按“send”。
關於定位的選定
在例子中,我們指定了採用GPS,實際上位置獲取可以通過衛星,運營商,以及第三方服務獲取,即有多個資訊來源。我們可以想系統查詢可用的位置資訊源,如下:
List<String> list = mgr.getAllProviders(); //mgr即LocationManagerfor(Iterator<String> i = list.iterator();i.hasNext();){ System.out.println("\t" + i.next()); }
我們可以重中進行選擇,或者讓使用者選擇,但是更好的方式是讓系統幫忙選擇。如下:
Criteria criteria = new Criteria(); String providerName = mgr.getBestProvider(criteria, true /*enabledOnly*/); //criteria不能填null,否則出現異常 LocationProvider provider = mgr.getProvider(providerName);
我們可以在criteria中加入一些條件,例如一些精度setAccuracy(),和一些位置資訊setAltitudeRequired( ),是否收費setCostAllowed( )等。不是隨有的條件都必須滿足,將為你匹配最好的一個,當然如果你設定了免費,不會選擇收費給你的。我們根據provider的名字獲得LocationProvider的物件,但一般不需要,我們知道provider的名字,就可以向系統請求位置資訊。
Location location = mgr.getLastKnownLocation(providerName); if(location != null) System.out.println("Get Location from " + providerName + " : " + location.getLatitude()+ "," + location.getLongitude());
Android採用getLastKnownLocation( )來查詢,而不是當前的實時資訊。有可能由於某種情況無法獲取,例如GPS沒有開啟,或正在啟動過程中,有可能返回null。返回的資訊可能不僅有經緯度,是否有具有海拔資訊,用location.hasAltitude()詢問,是否具有速度資訊,用hasSpeed()詢問。
到達某個位置的提醒觸發
當用戶位置到達某個目標附近 ,觸發提醒,這可以用在很多使用場景,LocationManager中可以通過addProximityAlert(),當在某位置附近可以調起pendingIntent。
public void addProximityAlert (double latitude /*維度*/, double longitude/*精度*/, float radius/*半徑範圍*/, long expiration/*失效,-1表示沒有失效,可以用removeProximityAlert()來進行人工刪除*/, PendingIntent intent /*觸發處理*/)
對比兩個location資料
對於前後獲取的location(可能來自不同的provider,也可能獲取位置資訊的條件發生變化,例如尋找多一顆衛星或少了一顆衛星,導致前後的精度有明顯差異),我們可以判斷哪個location更好地代表當前的地點。我們可以用location.getTime()來獲得定位資訊的更新時間,用location.getAccruacy()來獲取精度,用location.getProvider()反過來獲取providerName,用於進行提供者的比對。通過這些比較我們可以選取我們仍未最好的資料。在Android的開發者網站中給出 了選擇哪個location的例子。