日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android手机定位

發布時間:2024/1/23 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android手机定位 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

做移動互聯網就不太可能不碰手機端的開發。上周為了項目需要,俺也挽袖子掄胳膊開始寫起了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?
  • 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信息是否可以被接受。

    總結

    以上是生活随笔為你收集整理的android手机定位的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。