android手機定位

來源:互聯網
上載者:User

做移動互連網就不太可能不碰手機端的開發。上周為了項目需要,俺也挽袖子掄胳膊開始寫起了android程式,還好有java基礎,倒也上手快,寫了幾個小程式,主要都是關於定位方面的。
網上也搜得到一些相關的文章和教程,但給出的例子效果不太好,而且感覺只有其表,卻不明其理。因此寫出此文,分享一些我的經驗。雖然是以android為主,但是我想對其它平台的開發也應該有些協助。

這篇文章側重於制定一個合理的定位方案。

手機定位的方式 
先科普一些基礎知識吧。

最簡單的手機定位方式當然是通過GPS模組(現在大部分的智能機應該都有了)。GPS方式準確度是最高的,但是它的缺點也非常明顯:1,比較耗電;2,絕大部分使用者預設不開啟GPS模組;3,從GPS模組啟動到擷取第一次定位元據,可能需要比較長的時間;4,室內幾乎無法使用。這其中,缺點2,3都是比較致命的。需要指出的是,GPS走的是衛星通訊的通道,在沒有網路連接的情況下也能用。
另外一種常見的定位方式是基站定位。大致思路就是採集到手機上的基站ID號(cellid)和其它的一些資訊(MNC,MCC,LAC等等),然後通過網路訪問一些定位服務,擷取並返回對應的經緯度座標。基站定位的精確度不如GPS,但好處是能夠在室內用,只要網路通暢就行。
還有Wifi定位。和基站定位類似,這種方式是通過擷取當前所用的wifi的一些資訊,然後訪問網路上的定位服務以獲得經緯度座標。因為它和基站定位其實都需要使用網路,所以在Android也統稱為Network方式。
最後需要解釋一點的是AGPS方式。很多人將它和基站定位混為一談,但其實AGPS的本質仍然是GPS,只是它會使用基站資訊對擷取GPS進行輔助,然後還能對擷取到的GPS結果進行修正,所以AGPS要比傳統的GPS更快,準確度略高。

Android提供的定位介面 
在寫第一個程式之前,我對android的幻想是這樣的:提供了一個函數,能夠讓我直接從GPS模組中讀取經緯度座標,還有一個函數,能夠直接存取網路,獲得基站定位的結果。所以,我只需要調用調用函數就可以搞定這一切。
現實和理想總是有很大的差距。Android上的開發完全不是這麼回事兒。前面提到過,GPS模組從啟動到擷取資料之間時間會比較長,可能有2~3分鐘時間,所以,如果真有這麼一個函數,那麼你的程式可能會被這個函數阻塞幾分鐘。我想正是基於這樣的考慮,android上要想擷取定位資訊,必須使用非同步方式。

代碼大概是這個樣子:

locManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);  locListener = new LocationListener() {      @Override      public void onStatusChanged(String provider, int status,              Bundle extras) {          // TODO Auto-generated method stub      }      @Override      public void onProviderEnabled(String provider) {          // TODO Auto-generated method stub      }      @Override      public void onProviderDisabled(String provider) {          // TODO Auto-generated method stub      }      @Override      public void onLocationChanged(Location location) {          // TODO Auto-generated method stub          mobileLocation = location;      }  };  locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);  

這是從網上隨便摘一段。簡單解釋一下代碼:
首先,你需要建立一個LocationManager;
然後定義出自己的LocationListener,LocationListener包涵了好幾個成員函數,它們都是回呼函數。最重要的一個是“onLocationChanged”,這個函數是在android擷取了新的location資訊之後調用的,你可以在這個函數內來實現自己想要的功能。比如,你可以定義一個內部location變數,一旦這個函數被調用,就將內部location變數設定成最新的值;
最後,調用LocationManager.requestLocastionUpdates,它其實是將定義的locationListener註冊到android中。在上面的代碼中,這句話是說讓LocationListener監聽GPS_PROVIDER的變化。GPS_PROVIDER對應於android上的GPS模組擷取位置資訊,還有一個NETWORK_PROVIDER表示通過network方式擷取位置資訊。


問題

那麼接下來就有問題了,什麼時候能夠真正獲得手機的定位經緯度呢?等著onLocationChanged被調用吧。那它什麼時候會被調用?沒人知道。我寫過一個小程式,測試Network方式下註冊過listener之後(requestLocationUpdates函數)和onLocationChanged被調用之間的時間間隔。測試的網路條件很好。反覆觀察了幾次,大部分都可以在幾十毫秒內就返回了,但也有一些時候,時間間隔長達幾十秒。這意味著,你的使用者需要等上幾十秒才能有返回。
所以,第一個需要注意的地方是,不要一直等待你的回呼函數onLocationChanged被調用。你需要設定一個timeout機制。
這又會引入第二個問題。如果timeout了,但onLocationChanged仍然沒有返回,怎麼辦?難道只能提示使用者無法定位嗎?
別急,android還提供了一個函數:getlastKnowLocation。這個函數會返回android平台最後一次擷取到的位置資訊。比如,你可以這樣:

view plaincopy to clipboardprint?
  1. Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);  

所以,即便onLocationChanged沒有被調用,我們仍然可以擷取一個位置資訊。當然,這裡又引出了第三個問題:這個的傳回值值得信賴嗎?

如果用過一些LBS或者地圖程式,你會發現有一個現象:在某些時候你開啟地圖結果被定位到的地方是你上一次使用地圖程式的位置。這就是因為程式是採用getLastKnownLocation擷取的位置。這個問題的解決辦法是,需要定義一個標準判斷擷取到的Location是否可信。Android的Location這個類除了包涵有latitude,longitude,還包含有很多其他的資訊,比如何時擷取到的,通過哪種方式擷取到的,等等。程式員完全可以基於這些資訊來判斷擷取到的Location是否過時或者是否可信。

合理的方案

最後,說一下整體方案。Android的官方文檔【1】給出了推薦的方案:

 
首先註冊自己的LocationListener,讓它同時監聽GPS_PROVIDER和NETWORK_PROVIDER;
然後可以調用getLastKnownLocation獲得一個Location值,這個值可以作為一個備選值;
然後在一段使用者可接受的時間內,不斷接收從onLocationChanged返回的位置,並同之前的值做比較,選取其中的最佳;
最後,會剩下一個篩選後的最優結果,你需要判斷這個結果是否可接受。如果可以接受,返回給使用者,如果不行,告訴使用者無法定位。
整個過程你需要定義兩個重要的函數:一個是比較兩個Location資訊,返回其中好的那個;另一個函數則用來判斷Location資訊是否可以被接受。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.