安卓百度地圖(一)定位功能的實現、周邊POI的檢索

其他文章:
安卓百度離線地圖的下載以及使用
安卓百度地圖(二)地圖顯示以及離線地圖的下載使用
安卓百度地圖(三)繪制點、線等圖層信息
安卓百度地圖(四)城市,周邊,區域檢索
安卓百度地圖(五)百度地圖路線規劃
安卓百度地圖(六)鷹眼軌跡的上傳,歷史軌跡的顯示
安卓百度地圖(七)地理圍欄的建立與使用

本文主要針對百度定位sdk的api進行整理

一 定位簡介

百度地圖Android定位SDK提供GPS、基站、WiFi、地磁、藍牙、傳感器等多種定位方式,適用于室內、室外多種定位場景,具有出色的定位性能:定位精度高、覆蓋率廣、網絡定位請求流量小、定位速度快。
引用官方的圖片

在室內無gps時,百度定位就是利用的WiFi和基站定位的,在室外有gps時,百度是利用的android自帶的LocationManager進行定位,當然室外也可以用WiFi基站定位。

  • GPS定位:精度很高,幾米到十幾米,但是耗電嚴重。
  • WiFi定位:精度相對于GPS差一點,但是也能到十幾米、幾十米,也有上百米的誤差的,低耗電。
  • 基站定位:精度很差,一般都有幾百米,上千米的誤差。

二 百度地圖配置

關于百度地圖的配置,可以查看官網的詳解教程:傳送門

  • 登錄API控制臺,創建應用,獲取應用的AK。
  • 下載所需要的開發資源傳送門,解壓文件,將lib下的文件copy至app下的lib中,在app的buid文件中輸入
android {
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}
  • 添加AK
<meta-data
    android:name="com.baidu.lbsapi.API_KEY"
    android:value="開發者申請的AK" >
</meta-data>
  • 添加所需服務
//Application標簽中聲明service組件,每個App擁有自己單獨的定位service
<service
     android:name="com.baidu.location.f" 
    android:enabled="true" 
    android:process=":remote"> 
</service>
  • 添加功能權限:
<!-- 這個權限用于進行網絡定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!-- 這個權限用于訪問GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 用于訪問wifi網絡信息,wifi信息會用于進行網絡定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!-- 獲取運營商信息,用于支持提供運營商信息相關的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!-- 這個權限用于獲取wifi的獲取權限,wifi信息會用來進行網絡定位-->
<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" />
<!-- SD卡讀取權限,用戶寫入離線定位數據-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>

注意:安卓6.0系統以上,一些權限需要動態申請

三 百度地圖定位

1. 初始化LocationClient類

public LocationClient mLocationClient = null;;
public void onCreate()
{
     mLocationClient = new LocationClient(getApplicationContext());//聲明LocationClient類
     mLocationClient.registerLocationListener(myListener);//注冊監聽函數
}

2. 配置定位SDK參數

LocationClientOption mOption = new LocationClientOption();

/**
* 默認高精度,設置定位模式
* LocationMode.Hight_Accuracy 高精度定位模式:這種定位模式下,會同時使用
* LocationMode.Battery_Saving 低功耗定位模式:這種定位模式下,不會使用GPS,只會使用網絡定位。
* LocationMode.Device_Sensors 僅用設備定位模式:這種定位模式下,
*/
mOption.setLocationMode(LocationMode.Hight_Accuracy);

/**
* 默認是true,設置是否使用gps定位
* 如果設置為false,即使mOption.setLocationMode(LocationMode.Hight_Accuracy)也不會gps定位
*/
mOption.setOpenGps(true);

/**
* 默認gcj02,設置返回的定位結果坐標系,如果配合百度地圖使用,建議設置為bd09ll;
* 目前國內主要有以下三種坐標系:
1. wgs84:目前廣泛使用的GPS全球衛星定位系統使用的標準坐標系;
2. gcj02:經過國測局加密的坐標;
3. bd09:為百度坐標系,其中bd09ll表示百度經緯度坐標,bd09mc表示百度墨卡托米制坐標;
* 在國內獲得的坐標系類型可以是:國測局坐標、百度墨卡托坐標 和 百度經緯度坐標。
  在海外地區,只能獲得WGS84坐標。請在使用過程中注意選擇坐標。
*/
mOption.setCoorType("bd09ll");

/**
* 默認0,即僅定位一次;設置間隔需大于等于1000ms,表示周期性定位
* 如果不在AndroidManifest.xml聲明百度指定的Service,周期性請求無法正常工作
* 這里需要注意的是:如果是室外gps定位,不用訪問服務器,設置的間隔是3秒,那么就是3秒返回一次位置
  如果是WiFi基站定位,需要訪問服務器,這個時候每次網絡請求時間差異很大,設置的間隔是3秒,
  只能大概保證3秒左右會返回就一次位置,有時某次定位可能會5秒才返回
*/
mOption.setScanSpan(3000);

/**
* 默認false,設置是否需要地址信息
* 返回省、市、區、街道等地址信息,這個api用處很大,
  很多新聞類app會根據定位返回的市區信息推送用戶所在市的新聞
*/
mOption.setIsNeedAddress(true);

/**
* 默認false,設置是否需要位置語義化結果
* 可以在BDLocation.getLocationDescribe里得到,結果類似于“在北京天安門附近”
*/
mOption.setIsNeedLocationDescribe(true);

/**
* 默認false,設置是否需要設備方向傳感器的方向結果
* 一般在室外gps定位時,返回的位置信息是帶有方向的,但是有時候gps返回的位置也不帶方向,
  這個時候可以獲取設備方向傳感器的方向
* wifi基站定位的位置信息是不帶方向的,如果需要可以獲取設備方向傳感器的方向
*/
mOption.setNeedDeviceDirect(false);

/**
* 默認false,設置是否當gps有效時按照設定的周期頻率輸出GPS結果
* 室外gps有效時,周期性1秒返回一次位置信息,其實就是設置了
locationManager.requestLocationUpdates中的minTime參數為1000ms,1秒回調一個gps位置
* 如果設置了mOption.setScanSpan(3000),那minTime就是3000ms了,3秒回調一個gps位置
*/
mOption.setLocationNotify(false);

/**
* 默認true,定位SDK內部是一個SERVICE,并放到了獨立進程,設置是否在stop的時候殺死這個進程,默認不殺死
* 如果你已經拿到了你要的位置信息,不需要再定位了,不殺死留著干嘛
*/
mOption.setIgnoreKillProcess(true);

/**
* 默認false,設置是否需要POI結果,可以在BDLocation.getPoiList里得到
* POI就是獲取到的位置附近的一些商場、飯店、銀行等信息
*/
mOption.setIsNeedLocationPoiList(true);

/**
* 默認false,設置是否收集CRASH信息,默認收集
*/
mOption.SetIgnoreCacheException(false);

/**
* 默認false,設置定位時是否需要海拔高度信息,默認不需要,除基礎定位版本都可用
*/
mOption.setIsNeedAltitude(false);

mLocationClient.setLocOption(mOption);//設置定位參數

3. 發起定位

發起定位,便能夠從BDAbstractLocationListener監聽接口中獲取定位結果信息。

//mLocationClient為第二步初始化過的LocationClient對象
//調用LocationClient的start()方法,便可發起定位請求
mLocationClient.start();
//tart():啟動定位SDK;stop():關閉定位SDK。調用start()之后只需要等待定位結果自動回調即可。
//開發者定位場景如果是單次定位的場景,在收到定位結果之后直接調用stop()函數即可。
//如果stop()之后仍然想進行定位,可以再次start()等待定位結果回調即可。
//自v7.2版本起,新增LocationClient.reStart()方法,用于在某些特定的異常環境下重啟定位。

4.實現BDAbstractLocationListener接口

發起定位后,即可獲取所需要的信息

private class MyBDAbstractLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            //此處的BDLocation為定位結果信息類,通過它的各種get方法可獲取定位相關的全部結果    
           if (null != location && location.getLocType() != BDLocation.TypeServerError) {
             
           }   
        }
}

4.1 獲取基本定位信息

bdLocation.getLatitude();//緯度
bdLocation.getLongitude();//經度
bdLocation.getDirection();//定位方向
bdLocation.getRadius();//定位精度
bdLocation.getCoorType();//定位坐標類型
bdLocation.getLocType();//定位類型、定位錯誤返回碼
bdLocation.getLocTypeDescription();//對應的定位類型說明
bdLocation.getTime();//獲取經緯度服務器時間
//判斷用戶是在室內,還是在室外1:室內,0:室外,這個判斷不一定是100%準確的
bdLocation.getUserIndoorState();

4.2 獲取地址信息

注意:配置定位SDK參數中,添加獲取地址信息option.setIsNeedAddress(true);

bdLocation.getAddrStr();    //獲取詳細地址信息
bdLocation.getCountry();    //獲取國家
bdLocation.getProvince();    //獲取省份
bdLocation.getCity();    //獲取城市
bdLocation.getDistrict();    //獲取區縣
bdLocation.getStreet();    //獲取街道信息

4.3 獲取位置信息描述

注意:首先在配置定位SDK參數中,添加獲取位置信息描述option.setIsNeedLocationDescribe(true);

location.getLocationDescribe();    //獲取位置描述信息

4.4 周邊POI信息

獲取位置附近的一些商場、飯店、銀行等信息
注意:首先在配置定位SDK參數中,添加獲取周邊信息option.setIsNeedLocationPoiList(true);
在實現的BDAbstractLocationListener接口中,通過getPoiList()方法,即可獲取周邊信息

List<Poi> poiList = bdLocation.getPoiList(); //POI信息包括POI ID、名稱等,具體信息請參照類參考中POI類的相關說明

4.5 判斷定位類型

if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位結果
        bdLocation.getSpeed();// 速度 單位:km/h
        bdLocation.getSatelliteNumber();// 衛星數目
        bdLocation.getAltitude();// 海拔高度 單位:米
        bdLocation.getGpsAccuracyStatus();// *****gps質量判斷*****
        Toast.makeText(MainActivity.this, "gps定位成功", Toast.LENGTH_SHORT).show();

} else if (bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) {// 網絡定位結果
       // 運營商信息
        if (bdLocation.hasAltitude()) {// *****如果有海拔高度*****
            bdLocation.getAltitude();// 單位:米
        }
        (bdLocation.getOperators();   // 運營商信息
        Toast.makeText(MainActivity.this, "網絡定位成功", Toast.LENGTH_SHORT).show();

} else if (bdLocation.getLocType() == BDLocation.TypeOffLineLocation) {// 離線定位結果
        Toast.makeText(MainActivity.this, "離線定位成功,離線定位結果也是有效的", Toast.LENGTH_SHORT).show();

} else if (bdLocation.getLocType() == BDLocation.TypeServerError) {
        Toast.makeText(MainActivity.this, "服務端網絡定位失敗,可以反饋IMEI號和大體定位時間到loc-bugs@baidu.com,會有人追查原因", Toast.LENGTH_SHORT).show();

} else if (bdLocation.getLocType() == BDLocation.TypeNetWorkException) {
        Toast.makeText(MainActivity.this, "網絡不通導致定位失敗,請檢查網絡是否通暢", Toast.LENGTH_SHORT).show();

} else if (bdLocation.getLocType() == BDLocation.TypeCriteriaException) {
              
        Toast.makeText(MainActivity.this, "法獲取有效定位依據導致定位失敗,一般是由于手機的原因,處于飛行模式下一般會造成這種結
果,可以試著重啟手機", Toast.LENGTH_SHORT).show();
}

4.6 國內外位置判斷

//此處的BDLocation為定位結果信息類,通過它的各種get方法可獲取定位相關的全部結果
//以下只列舉與國內外判斷相關的內容
//更多結果信息獲取說明,請參照類參考中BDLocation類中的說明
//BDLocation.getLocationWhere()方法可獲得當前定位點是否是國內,它的取值及含義如下:
//BDLocation.LOCATION_WHERE_IN_CN:當前定位點在國內;
//BDLocation.LOCATION_WHERE_OUT_CN:當前定位點在海外;
//其他:無法判定。

4.7 位置提醒

定位SDK支持位置提醒功能,位置提醒最多提醒3次,3次過后將不再提醒。假如需要再次提醒、或者要修改提醒點坐標,都可通過函數SetNotifyLocation()來實現。

4.7.1 注冊監聽函數

 //注冊監聽函數
 mLocationClient.registerNotify(myListener);    

4.7.2 實現位置監聽的回調

定義MyNotifyLister類,繼承BDNotifyListener,實現位置監聽的回調。
public class MyNotifyLister extends BDNotifyListener {
    public void onNotify(BDLocation mlocation, float distance){
        //已到達設置監聽位置附近
    }           
}

4.7.3 實現設置位置消息提醒

調用BDNotifyListener的setNotifyLocation方法,實現設置位置消息提醒。
myListener.setNotifyLocation(40.0f, 116.0f, 3000, mLocationClient.getLocOption().getCoorType());
//設置位置提醒,四個參數分別是:緯度,經度,距離范圍,坐標系類型(gcj02,gps,bd09,bd09ll)

4.7.4 啟動定位

啟動定位,SDK便會自動開啟位置消息提醒的監聽。
調用LocationClient的start()方法,啟動定位。核心代碼如下:
mLocationClient.start();
//mLocationClient為第二步初始化過的LocationClient對象
//調用LocationClient的start()方法,開啟定位

4.7.5 取消監聽

調用BDNotifyListener的removeNotifyEvent方法,實現取消位置監聽。核心代碼如下:
myListener.removeNotifyEvent(myListener);
//myListener為第二步中定義過的BDNotifyListener對象
//調用執行removeNotifyEvent方法,即可實現取消監聽

5. 釋放資源

mLocationClient.unregisterListener(myLocationListener); //注銷掉監聽
mLocationClient.stop(); //停止定位

本文主要做于收集整理筆記使用,關于文章的源碼,請移步我的GitHub

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,517評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,087評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,521評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,493評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,207評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,603評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,624評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,813評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,364評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,110評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,305評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,874評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,532評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,953評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,209評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,033評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,268評論 2 375