以前個人項目中的位置定位使用的是基站方法,使用的Google提供的API,可是前天中午忽然就不返回數據了,到網上搜了一下才知道,Google的接口不提供服務了,基於時間緊迫用了百度現有的SDK,可是在使用過程當中第一次獲取位置老是空值,通過屢次實驗終於成功。固然,若是須要精確的位置,你能夠再加上位置偏移算法。個人應用對這個要求不高,就沒作,一搜一大把,就很少說了。 java
下面這段話來自 百度地圖API>定位SDK android
百度地圖定位SDK免費對外開放,無需申請key。在使用百度定位SDK前,但願先閱讀百度定位地圖的API。若是使用則被視爲對使用條款的徹底接收,並贊成接收本協議的各項條款約束。
目前百度地圖定位SDK只支持Android和Symbian量大平臺,其餘產品正在開放中。 git
下面事例是使用Android平臺的部分代碼。對於這個平臺百度的開放人員已經寫了完整的demo,把工程導入到eclipse中以後通常沒有錯誤,若是報錯的話,eclipse也會給出提示。通常能夠經過將propertie.properties文件名字改成default.properties就能夠了,若是還有錯誤的話,顯示工程activity錯誤啊什麼的,就是SDK版本不對的問題了,你能夠經過他的manifest文件查看<uses-sdk android:minSdkVersion="8" />找到這個最小值,好比我下載的是2.6他的最低版本是5,我eclipse默認版本是8,就能夠同過右鍵單擊該工程,選擇最下面那個properties項,而後在彈出對話框的右側列表中選擇Android,在左側選擇API level爲5,也就是2.0,而後肯定。就木有問題了。 算法
下面說一下使用該API的具體步驟:
也能夠查看百度定位SDK本身的開發指南 服務器
一、首先第一步就是搭配環境:
①先將百度demo中的libs文件夾複製到本身的工程。(別忘記把jar包build path)
②而後複製 網絡
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" android:permission="android.permission.BAIDU_LOCATION_SERVICE"> <intent-filter> <action android:name="com.baidu.location.service_v2.6"></action> </intent-filter> </service>
到manifest的application 節點
接下來複制百度地位SDK須要的permission app
<permission android:name="android.permission.BAIDU_LOCATION_SERVICE"></permission> <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"> </uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"> </uses-permission> <uses-permission android:name="android.permission.READ_PHONE_STATE"> </uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"> </uses-permission> <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
③ 接下來就能夠在代碼中放心的使用百度定位SDK了.
下面是來自百度的提醒.須要注意的是第五條,由於咱們第一次常常定位不到位置: eclipse
一、您須要確保程序編譯經過。若是對本身寫的代碼有疑問,能夠下載官方高級示例,查看標準源代碼。 ide
二、請確保網絡通暢,不管是鏈接wifi仍是使用2G/3G信號。 測試
三、定位SDK的調用必須在主線程中。
四、必須在定位SDK啓動前設定好參數,例如是否使用GPS,掃描時間間隔設置等。咱們強烈建議您設置本身的prodName,並保管好,這樣方便咱們爲您提供更好的定位服務。
五、定位SDK start以後當即執行,這種狀況下很難定位成功,由於定位SDK剛開始啓動尚未獲取到定位信息。這時getlocation通常爲null。若是是要獲取位置成功,能夠在listerner中添加一個判斷若是strData爲空,則再發起一次定位。
六、定位覆蓋率大概在98%。就是說有2%可能服務器沒有數據,因此定位會失敗。只須要走到別的地方,或者多試幾回便可成功定位。
七、請使用真機。在虛擬機上沒法進行定位測試。
下面就是個人事例代碼:
具體思路是:將開啓和獲取位置的代碼分開來作,能夠在程序剛開啓的時候就start。由於據上面所說,有時候可能兩分鐘才能獲取到位置,對於咱們須要展現信息來講,這是絕對不能夠的。若是在主線程卡兩分鐘後果可想而知的。
須要說名的是:我這裏沒有設置時間間隔public void setScanSpan ( int ) //設置定時定位的時間間隔。單位ms,若是不設置或者所設置的整數值小於1000(ms)時,採用第一次定位模式。每調用一次requestLocatin(),定位SDK會發起一次定位。請求定位與監聽結果一一對應;若是所設的整數值大於等於1000(ms)時,定位SDK內部使用定時定位模式。調用requestLocation( )後,每隔設定的時間,定位SDK就會進行一次定位。若是定位SDK根據定位依據發現位置沒有發生變化,就不會發起網絡請求,返回上一次定位的結果;若是發現位置改變,就進行網絡請求進行定位,獲得新的定位結果。定時定位時,調用一次requestLocation,會定時監聽到定位結果。設定了定時定位後,能夠熱切換成一次定位,須要從新設置時間間隔小於1000(ms)便可。locationClient對象stop後,將再也不進行定位。若是設定了定時定位模式後,屢次調用requestLocation(),則是每隔一段時間進行一次定位,同時額外的定位請求也會進行定位,但頻率不會超過1秒一次。
import android.content.Context; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.palmdeal.entity.LocationInfo.SItude; import com.palmdeal.util.Logger; public class LocationProvider { private static LocationClient mLocationClient = null; private static SItude station = new SItude(); private static MyBDListener listener = new MyBDListener(); Context context; public LocationProvider(Context context) { super(); this.context = context; } public void startLocation() { mLocationClient = new LocationClient(context); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); // 打開gps option.setCoorType("bd09ll"); // 設置座標類型爲bd09ll option.setPriority(LocationClientOption.NetWorkFirst); // 設置網絡優先 option.setProdName("demo"); // 設置產品線名稱 mLocationClient.setLocOption(option); mLocationClient.registerLocationListener(listener); mLocationClient.start();//將開啓與獲取位置分開,就能夠儘可能的在後面的使用中獲取到位置 } /** * 中止,減小資源消耗 */ public void stopListener() { if (mLocationClient != null && mLocationClient.isStarted()) { mLocationClient.stop(); mLocationClient = null; } } /** * 更新位置並保存到SItude中 */ public void updateListener() { if (mLocationClient != null && mLocationClient.isStarted()) { mLocationClient.requestLocation(); Logger.i("update the location"); } } /** * 獲取經緯度信息 * * @return */ public SItude getLocation() { return station; } private static class MyBDListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location.getCity() == null) { int type = mLocationClient.requestLocation(); Logger.e("first request false" + type); } station.latitude = location.getLatitude(); station.longitude = location.getLongitude(); } @Override public void onReceivePoi(BDLocation arg0) { // return } } }
public class LocationInfo { /** 經緯度信息結構體 */ public static class SItude { /** 緯度 */ public double latitude; /** 經度 */ public double longitude; } }在使用的時候,在一開始就開啓LocationClient,即調用startLocation()方法。個人是在服務服務中的onCreate中調用的,而後在代碼中這樣使用:
LocationInfo.SItude station = location.getLocation(); if (station.latitude == 0.0 && station.longitude == 0.0) { location.updateListener(); station = location.getLocation(); } if (station.latitude == 0.0 && station.longitude == 0.0) { return "未定位到您如今的位置,請重試"; } location.stopListener();使用上面的方法後,第一次使用都能拿到位置信息。