1. 程式人生 > >Pro Android學習筆記 一一六 Location 2 LocationManager的位置獲取

Pro Android學習筆記 一一六 Location 2 LocationManager的位置獲取

LocationManager提供兩個主要功能:1、獲取裝置的地理位置(經緯度);2、當裝置進入制定的地理位置,通過通過intent通知。

獲取位置資訊的基本方法

簡單的程式碼片段如下:

private void getMyLocation(){    //1、獲取LocationManager,LocationManager是系統級別的服務   LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);     //2、獲取有效的provider,並顯示出來     List<String> providerlist = manager.getAllProviders();

           showProvider(providerlist);            //3、在LocationManger獲取某個provider的位置資訊            /* 獲取位置更新使用getLastKnownLocation(),引數為provider的名字,系統提供預定義的有LocationManager.GPS_PROVIDER、LocationManager.NETWORK_PROVIDER以及PASSIVE_PROVIDER。如果未能獲取任何資訊,getLastKnownLocation(provider)將返回null。Location可以獲取provider的名字,經緯度,高度,速度,方位(bearing),精確度等等,用getXXX()獲取,對於非常規資料在獲取之前可以通過hasXXX()來判斷有否該資訊 */
    Location locate = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);    showInfo("loc = " + loc);     } private void showProvider(List<String> list){     showInfo("show providers : ");     for(int i = 0 ; i < list.size(); i ++){          showInfo("(" +i +")" + list.get(i));     } } private void showInfo(String info){     Log.i("WEI",info); }

此外,我們必須在AndroidManifest.xml授予相應的許可權。相關許可權有兩個: 1、android.permission.ACCESS_FINE_LOCATION;2、android.permission.ACCESS_COARSE_LOCATION。其中fine(精確)已經涵蓋了coarse(粗糙),如果我們定義了fine,就不需要在授予coarse。GPS和Passive需要fine,而network可以使用coarse。

下面是檢視provider的結果:

network即通過基站或者wifi的方式獲取位置資訊,GPS不用解釋。Passive,即被動方式,是位置更新監測器,當其他App獲取地理位置時,向你的App進行位置更新,而你的APP並不需要請求位置更新。至於hybrid是混合方式,不是Android系統的標準方式。而在模擬器中預設提供gps和passive這兩種方式。

模擬器上的位置模擬

在模擬器,我們可以通過DDMS的Emulator control來設定位置資訊。

此外我們還可以通過telnet到模擬器,通過命令上進行設定,下面是通過SecureCRT telnet到值模擬器(telnet localhost 5554),相關命令為geo fix <latitude> <longitude>或者geo fix <latitude> <longitude> <altitude>

獲取provider

getAllProviders()獲得的提供商列表,而getProvider(LocationManager.GPS_PROVIDER)則可以獲取指定供應商的名稱。但是這兩種獲取方式,獲得包括目前無法訪問的,也就是最終返回的Location為null。

我們可以通過getProviders(true),只返回有效的供應商列表,或者用isProviderEnabled(String providerName)來看看供應商是否有效。但是這同樣亦有問題,如果我們關閉手機的GPS,返回的列表中沒有gps,或者查詢到無效,當時當我們開啟手機的GPS時,有可能並沒有搜尋到衛星,這是gps仍出現在有效的供應商列表,或者查詢是enabled的,但location仍會返回null。

我們希望能獲得最適合我們需求的供應商,相關程式碼如下:

private void getMyLocation1(){     LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);    //設定我們的標準Criteria,可以用setXXX(),例如criteria.setAccuracy(int);提出我具體的要求,例如精度要求等,如果沒有什麼特別的要求,也就無需進行設定    Criteria criteria = new Criteria();     //通過getBestProvider獲得滿足要求的最佳供應商,也可以通過getProviders(criteria, true)獲取符合要求的供應商列表。在沒有搜尋到足夠衛星時,系統會返回其他方式,如network。     String providerName = manager.getBestProvider(criteria, true/*true表示enabledOnly*/);    showInfo("Best provider is " + providerName);        if(providerName != null){         Location locate = manager.getLastKnownLocation(providerName);         showLocation(locate);     } }

進行相關設定

裝置可能沒有開啟GPS,獲取關閉了所有的地理資訊獲取方法,如果檢查到沒有開啟地理服務,彈出系統設定給使用者,由使用者進行設定,在設定結束後,再次進行位置獲取。相關程式碼如下:

private LocationManager manager = null; private void getMyLocation2(){     if(manager == null)         manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);    boolean isGpsAvalible = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);    if(!isGpsAvalible){ //開啟location設定的activity       startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0);    }else{         getFromGps();     } }    @Override //當用戶設定後按返回鍵,觸發onActivityResultprotected void onActivityResult(int requestCode, int resultCode, Intent data) {     super.onActivityResult(requestCode, resultCode, data);     getFromGps(); } private void getFromGps(){     //使用者不一定會在系統設定中開啟,故需要再次檢測!     boolean isGpsAvalible = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);    if(isGpsAvalible){         Location location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);        showLocation(location);     } }

Location資訊

我們可以用hasXXX()來獲得是否供應商提供了某個位置資訊,用getXXX()來獲取具體的位置資訊,下面是例子。如果提供商是GSP,衛星的數目放在extra中。

Log.d("WEI","longtitude = " + loc.getLongitude()); Log.d("WEI","lantitude = " + loc.getLatitude()); boolean isAvalible = loc.hasAccuracy(); Log.d("WEI","hasAccuracy = " + loc.hasAccuracy()); if(isAvalible) Log.d("WEI","accuracy = " + loc.getAccuracy()); Bundle b = loc.getExtras(); if(b!= null){       Log.d("WEI","satellites num = " + b.getInt("satellites")); }

Location類提供兩個地點之間的距離計算,distanceTo()和靜態方法distanceBetween()。這裡給出的是最短的地理距離,而非兩者間的交通距離(例如駕車距離),如果要獲得最短的駕車線路和距離,需要地圖供應商,例如Google Map。

 【注意】雖然,GPS在實際應用中更為常用,但在室內進行開發調測中,使用network更為穩定,因此如果是用實體機調測,建議採用network方式。對於模擬器,最好使用具有Google APIs的版本,以確保DDMS中位置模擬的正常使用。