百度地圖開發之實現運動軌跡
近日想在android平臺下進行一個基於地理位置的APP開發,於是想到了利用百度地圖的API進行開發。於是參考了網上的一些程式碼以及相關知識的分享,現在記錄一下在百度地圖上描繪出運動軌跡的開發過程!
首先,百度地圖定位功能的一個重要的類就是 LocationClient。
此處需要注意:LocationClient類必須在主執行緒中宣告。需要Context型別的引數。
Context需要時全程序有效的context,推薦用getApplicationConext獲取全程序有效的context
public LocationClient mLocationClient = null;
public BDLocationListener myListener = new MyLocationListener();
public void onCreate() {
mLocationClient = new LocationClient(getApplicationContext()); //宣告LocationClient類
mLocationClient.registerLocationListener( myListener ); //註冊監聽函式
}
LocationClient類是定位SDK的核心類,具體方法如下: 構造類:
public LocationClient ( Context ) //須在主執行緒中宣告
設定引數:
public void setLocOption ( LocationClientOption )
引數:配置定位SDK,詳見LocationClientOption類。 說明:2.x版本以後的定位提供API介面,用以在API執行過程中,支援熱切換配置引數。
註冊監聽函式:
public void registerLocationListener ( BDLocationListener )
引數:詳見BDLocationListener類。 說明:當沒有註冊監聽函式時,無法發起網路請求。
註冊位置提醒監聽事件:
public void registerNotify ( BDNotifyListener mNotify )
開啟/關閉:
public void start();
public void stop();
start:啟動定位SDK。
stop:關閉定位SDK。呼叫stop之後,設定的引數LocationClientOption仍然保留。
發起定位:
public int requestLocation()
發起定位,非同步獲取當前位置。因為是非同步的,所以立即返回,不會引起阻塞。定位結果在ReceiveListener的方法OnReceive方法的引數中返回。
需要注意:當定位SDK從定位依據判定,位置和上一次沒發生變化,而且上一次定位結果可用時,則不會發起網路請求,而是返回上一次的定位結果。 返回值:
0:正常發起了定位。
1:服務沒有啟動。
2:沒有監聽函式。
6:請求間隔過短。 前後兩次請求定位時間間隔不能小於1000ms。
請求離線定位:
離線定位功能:使用者請求過得基站定位結果會快取在本地檔案。離線定位結果為快取結果,精度低於線上的定位結果。
離線定位結果沒有地址資訊。
public int requestOfflineLocation()
發起離線定位,非同步獲取當前位置。因為是非同步的,所以立即返回,不會引起阻塞。定位結果在ReceiveListener的方法OnReceive方法的引數中返回。
返回值:
0:正常發起了定位。
1:服務沒有啟動。
2:沒有監聽函式。
取消監聽函式:
public void unRegisterLocationListener(BDLocationListener listener)
取消監聽函式。
位置提醒相關函式:
//註冊位置提醒監聽事件
public void registerNotify(BDNotifyListener mNotify)
//取消位置提醒監聽事件
public void removeNotifyEvent(BDNotifyListener mNotify)
實現BDLocationListener介面
BDLocationListener介面有2個方法需要實現: 1.接收非同步返回的定位結果,引數是BDLocation型別引數。
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null)
return ;
StringBuffer sb = new StringBuffer(256);
sb.append("time : ");
sb.append(location.getTime());
sb.append("\nerror code : ");
sb.append(location.getLocType());
sb.append("\nlatitude : ");
sb.append(location.getLatitude());
sb.append("\nlontitude : ");
sb.append(location.getLongitude());
sb.append("\nradius : ");
sb.append(location.getRadius());
if (location.getLocType() == BDLocation.TypeGpsLocation){
sb.append("\nspeed : ");
sb.append(location.getSpeed());
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber());
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation){
sb.append("\naddr : ");
sb.append(location.getAddrStr());
}
logMsg(sb.toString());
}
}
BDLocation類,封裝了定位SDK的定位結果,在BDLocationListener的onReceive方法中獲取。通過該類使用者可以獲取error code,位置的座標,精度半徑等資訊。具體方法如下:
獲取error code:
public int getLocType ( )
返回值:
61 : GPS定位結果
62 : 掃描整合定位依據失敗。此時定位結果無效。
63 : 網路異常,沒有成功向伺服器發起請求。此時定位結果無效。
65 : 定位快取的結果。
66 : 離線定位結果。通過requestOfflineLocaiton呼叫時對應的返回結果
67 : 離線定位失敗。通過requestOfflineLocaiton呼叫時對應的返回結果
68 : 網路連線失敗時,查詢本地離線定位時對應的返回結果
161: 表示網路定位結果
162~167: 服務端定位失敗
502:key引數錯誤
505:key不存在或者非法
601:key服務被開發者自己禁用
602:key mcode不匹配
501~700:key驗證失敗
如果不能定位,請記住這個返回值,併到我們的hi群或者貼吧中交流。若返回值是162~167,請傳送郵件至[email protected]反饋。
獲取經緯度座標:
public double getLatitude ( ) //獲取維度
public double getLongitude ( ) //獲取經度
獲取定位的座標。座標的型別在setLocationClientOption方法中設定。
獲取定位精度:
public boolean hasRadius ( ) //判斷是否有定位精度半徑
public float getRadius ( ) //獲取定位精度半徑,單位是米
獲取文字描述的地址(反地理編碼):
public String getAddrStr ( ) //獲取反地理編碼
只有使用網路定位的情況下,才能獲取當前位置的反地理編碼描述。
自定位SDK2.6版本之後,支援獲取省/市/區分級地理資訊:
public String getProvince ( ) //獲取省份資訊
public String getCity ( ) //獲取城市資訊
public String getDistrict ( ) //獲取區縣資訊
獲取手機方向資訊:
public float getDirection()
//獲得手機方向,範圍【0-360】,手機上部正朝向北的方向為0°方向
設定定位引數
設定定位引數包括:定位模式(高精度定位模式,低功耗定位模式和僅用裝置定位模式),返回座標型別,是否開啟GPS等等。
高精度定位模式:這種定位模式下,會同時使用網路定位和GPS定位,優先返回最高精度的定位結果;
低功耗定位模式:這種定位模式下,不會使用GPS,只會使用網路定位(Wi-Fi和基站定位)
僅用裝置定位模式:這種定位模式下,不需要連線網路,只使用GPS進行定位,這種模式下不支援室內環境的定位
eg:
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationMode.Hight_Accuracy);//設定定位模式
option.setCoorType(“bd09ll”);//返回的定位結果是百度經緯度,預設值gcj02
option.setScanSpan(5000);//設定發起定位請求的間隔時間為5000ms
option.setIsNeedAddress(true);//返回的定位結果包含地址資訊
option.setNeedDeviceDirect(true);//返回的定位結果包含手機機頭的方向
mLocClient.setLocOption(option);
LocationClientOption類,該類用來設定定位SDK的定位方式,具體方法如下:
設定定位模式:
//Hight_Accuracy高精度、Battery_Saving低功耗、Device_Sensors僅裝置(GPS)
public void setLocationMode(LocationMode mode)
設定開啟GPS:
setOpenGps( boolean )
設定是否開啟gps,使用gps前提是使用者硬體開啟gps。預設是不開啟gps的。
設定是否需要裝置方向資訊:
//在網路定位中,獲取手機機頭所指的方向
public void setNeedDeviceDirect(boolean)
設定是否需要地址資訊:
使用setIsNeedAddress(boolean)
設定是否要返回地址資訊,預設為無地址資訊。
public void setAddrType ( String )
String 值為 all時,表示返回地址資訊,其他值都表示不返回地址資訊。
設定座標型別:
設定返回值的座標型別。
public void setCoorType ( String )
我們支援返回若干種座標系,包括國測局座標系、百度座標系,需要更多座標系請聯絡我們,需要深度合作。目前這些引數的程式碼為。因此需要在請求時指定型別,如果不指定,預設返回百度座標系。注意當僅輸入IP時,不會返回座標。目前這些引數的程式碼為
返回國測局經緯度座標系 coor=gcj02
返回百度墨卡託座標系 coor=bd09
返回百度經緯度座標系 coor=bd09ll
百度手機地圖對外介面中的座標系預設是bd09ll,如果配合百度地圖產品的話,需要注意座標系對應問題。
有關座標系的更多問題,請看常見問題
設定產品線名稱:
public void setProdName ( String )
設定產品線名稱。強烈建議您使用自定義的產品線名稱,方便我們以後為您提供更高效準確的定位服務。
設定定位時間間隔:
public void setScanSpan ( int ) //設定定時定位的時間間隔。單位ms
說明:
當所設的整數值大於等於1000(ms)時,定位SDK內部使用定時定位模式。呼叫requestLocation( )後,每隔設定的時間,定位SDK就會進行一次定位。如果定位SDK根據定位依據發現位置沒有發生變化,就不會發起網路請求,返回上一次定位的結果;如果發現位置改變,就進行網路請求進行定位,得到新的定位結果。定時定位時,呼叫一次requestLocation,會定時監聽到定位結果。
當不設此項,或者所設的整數值小於1000(ms)時,採用一次定位模式。每呼叫一次requestLocation( ),定位SDK會發起一次定位。請求定位與監聽結果一一對應。
設定了定時定位後,可以熱切換成一次定位,需要重新設定時間間隔小於1000(ms)即可。locationClient物件stop後,將不再進行定位。如果設定了定時定位模式後,多次呼叫requestLocation(),則是每隔一段時間進行一次定位,同時額外的定位請求也會進行定位,但頻率不會超過1秒一次。
設定位置提醒介面:
public void registerNotify( BDNotifyListener mNotify )
LocationClient註冊位置提醒監聽事件
public void removeNotifyEvent( BDNotifyListener mNotify )
LocationClient取消位置提醒監聽事件
發起定位請求
發起定位請求。請求過程是非同步的,定位結果在上面的監聽函式onReceiveLocation中獲取。
if (mLocClient != null && mLocClient.isStarted())
mLocClient.requestLocation();
else
Log.d(“LocSDK5”, “locClient is null or not started”);
發起離線定位請求
發起離線定位請求。請求過程是非同步的,定位結果在上面的監聽函式onReceiveLocation中獲取。
getLocTypte = BDLocation.TypteOfflineLocation || BDLocation.TypeOfflineLocationFail
表示是離線定位請求返回的定位結果
if (mLocClient != null && mLocClient.isStarted())
mLocClient.requestOfflineLocation();
位置提醒使用
位置提醒最多提醒3次,3次過後將不再提醒。 假如需要再次提醒,或者要修改提醒點座標,都可通過函式SetNotifyLocation()來實現。
//位置提醒相關程式碼
mNotifyer = new NotifyLister();
mNotifyer.SetNotifyLocation(42.03249652949337,113.3129895882556,3000,”gps”);//4個引數代表要位置提醒的點的座標,具體含義依次為:緯度,經度,距離範圍,座標系型別(gcj02,gps,bd09,bd09ll)
mLocationClient.registerNotify(mNotifyer);
//註冊位置提醒監聽事件後,可以通過SetNotifyLocation 來修改位置提醒設定,修改後立刻生效。
//BDNotifyListner實現
public class NotifyLister extends BDNotifyListener{
public void onNotify(BDLocation mlocation, float distance){
mVibrator01.vibrate(1000);//振動提醒已到設定位置附近
}
}
//取消位置提醒
mLocationClient.removeNotifyEvent(mNotifyer);
使用地理圍欄服務Beta
地理圍欄服務提供的是基於位置的提醒服務,相對於SDK原來提供的位置提醒功能,地理圍欄服務通過SDK本身的內部邏輯,大幅度降低位置提醒服務的功耗情況。通過使用地理圍欄服務,第三方APP可以在低能耗的模式下輕鬆實現位置提醒服務。
初始化GeofecenClient類
此處需要注意:GeofenceClient類必須在主執行緒中宣告。需要Context型別的引數。
Context需要時全程序有效的context,推薦用getApplicationConext獲取全程序有效的context。
public GeofenceClient mGeofenceClient = null;
public void onCreate() {
mGeofenceClient = new GeofenceClient(getApplicationContext();
}
實現新增和刪除圍欄的回撥介面
新增圍欄回撥:OnAddBDGeofencesResultListener
實現如下:
public class AddGeofenceListener implements OnAddBDGeofencesResultListener {
@Override
public void onAddBDGeofencesResult(int statusCode, String geofenceRequestId) {
if (statusCode == BDLocationStatusCodes.SUCCESS) {
//圍欄建立成功
}}}
刪除圍欄回撥:OnRemoveBDGeofencesResultListener
實現如下:
public class RemoveFenceListener implements OnRemoveBDGeofencesResultListener {
@Override
public void onRemoveBDGeofencesByRequestIdsResult(int statusCode, String[] geofenceRequestIds) {
if (statusCode == BDLocationStatusCodes.SUCCESS) {
//圍欄刪除成功
}}}
實現並註冊OnGeofenceTriggerListener回撥介面
public class GeofenceEnterLister implements OnGeofenceTriggerListener {
@Override
public void onGeofenceTrigger(String geofenceRequestId) {
//進入圍欄,圍欄Id = geofenceRequestId
}
@Override
public void onGeofenceExit(String geofenceRequestId) {
//退出圍欄,圍欄Id = geofenceRequestId
}
//註冊並開啟圍欄掃描服務
mGeofenceClient .registerGeofenceTriggerListener(new GeofenceEnterLister());
mGeofenceClient.start();
}
設定圍欄引數
圍欄引數包括:id:圍欄Id、x,y:圍欄座標點經緯度、name、半徑型別(目前只支援半徑在500m以內的圍欄)、expir:圍欄的有效時間,單位毫秒(最長可以設定1個月)、coordType:座標型別(COORD_TYPE_BD09、COORD_TYPE_BD09LL、COORD_TYPE_GCJ)、
具體如下:
BDGeofence fence = new BDGeofence.Builder().setGeofenceId(id).
setCircularRegion(x, y, type)
. setExpirationDruation(expir)
. setCoordType(coordType)
.build();
發起圍欄新增和刪除請求
//新增一個圍欄:
mGeofenceClient.addBDGeofence(fence, new AddGeofenceListener());
//刪除,指定要刪除圍欄的名字列表
List fences = new ArrayList();
fences.add(fenceId);
mGeofenceClient. removeBDGeofences(fences, new RemoveFenceListener());
需要注意的問題
定位SDK必須註冊GPS和網路的使用許可權。
使用定位SDK請保證網路連線通暢(GPS定位方式不需要連網)。
我們強烈建議您設定自己的prodName,並保管好,這樣方便我們為您提供更好的定位服務。
若需要返回的定位結果裡包含地址資訊,請保證網路連線。
定位SDK可以返回bd09、bd09ll、gcj02三種類型座標,若需要將定位點的位置通過百度Android地圖 SDK進行地圖展示,請返回bd09ll,將無偏差的疊加在百度地圖上。
有的移動裝置鎖屏後為了省電會自動關閉網路連線,此時網路定位模式的定位失效。此外,鎖屏後移動裝置若進入cpu休眠,定時定位功能也失效。若您需要實現在cpu休眠狀態仍需定時定位,可以用alarmManager 實現1個cpu可叫醒的timer,定時請求定位。