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

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

本文主要針對(duì)百度定位sdk的api進(jìn)行整理

一 定位簡(jiǎn)介

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

在室內(nèi)無(wú)gps時(shí),百度定位就是利用的WiFi和基站定位的,在室外有g(shù)ps時(shí),百度是利用的android自帶的LocationManager進(jìn)行定位,當(dāng)然室外也可以用WiFi基站定位。

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

二 百度地圖配置

關(guān)于百度地圖的配置,可以查看官網(wǎng)的詳解教程:傳送門

  • 登錄API控制臺(tái),創(chuàng)建應(yīng)用,獲取應(yīng)用的AK。
  • 下載所需要的開發(fā)資源傳送門,解壓文件,將lib下的文件copy至app下的lib中,在app的buid文件中輸入
android {
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}
  • 添加AK
<meta-data
    android:name="com.baidu.lbsapi.API_KEY"
    android:value="開發(fā)者申請(qǐng)的AK" >
</meta-data>
  • 添加所需服務(wù)
//Application標(biāo)簽中聲明service組件,每個(gè)App擁有自己?jiǎn)为?dú)的定位service
<service
     android:name="com.baidu.location.f" 
    android:enabled="true" 
    android:process=":remote"> 
</service>
  • 添加功能權(quán)限:
<!-- 這個(gè)權(quán)限用于進(jìn)行網(wǎng)絡(luò)定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!-- 這個(gè)權(quán)限用于訪問GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 用于訪問wifi網(wǎng)絡(luò)信息,wifi信息會(huì)用于進(jìn)行網(wǎng)絡(luò)定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!-- 獲取運(yùn)營(yíng)商信息,用于支持提供運(yùn)營(yíng)商信息相關(guān)的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!-- 這個(gè)權(quán)限用于獲取wifi的獲取權(quán)限,wifi信息會(huì)用來(lái)進(jìn)行網(wǎng)絡(luò)定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!-- 用于讀取手機(jī)當(dāng)前的狀態(tài)-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!-- 寫入擴(kuò)展存儲(chǔ),向擴(kuò)展卡寫入數(shù)據(jù),用于寫入離線定位數(shù)據(jù)-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!-- 訪問網(wǎng)絡(luò),網(wǎng)絡(luò)定位需要上網(wǎng)-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- SD卡讀取權(quán)限,用戶寫入離線定位數(shù)據(jù)-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>

注意:安卓6.0系統(tǒng)以上,一些權(quán)限需要?jiǎng)討B(tài)申請(qǐng)

三 百度地圖定位

1. 初始化LocationClient類

public LocationClient mLocationClient = null;;
public void onCreate()
{
     mLocationClient = new LocationClient(getApplicationContext());//聲明LocationClient類
     mLocationClient.registerLocationListener(myListener);//注冊(cè)監(jiān)聽函數(shù)
}

2. 配置定位SDK參數(shù)

LocationClientOption mOption = new LocationClientOption();

/**
* 默認(rèn)高精度,設(shè)置定位模式
* LocationMode.Hight_Accuracy 高精度定位模式:這種定位模式下,會(huì)同時(shí)使用
* LocationMode.Battery_Saving 低功耗定位模式:這種定位模式下,不會(huì)使用GPS,只會(huì)使用網(wǎng)絡(luò)定位。
* LocationMode.Device_Sensors 僅用設(shè)備定位模式:這種定位模式下,
*/
mOption.setLocationMode(LocationMode.Hight_Accuracy);

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

/**
* 默認(rèn)gcj02,設(shè)置返回的定位結(jié)果坐標(biāo)系,如果配合百度地圖使用,建議設(shè)置為bd09ll;
* 目前國(guó)內(nèi)主要有以下三種坐標(biāo)系:
1. wgs84:目前廣泛使用的GPS全球衛(wèi)星定位系統(tǒng)使用的標(biāo)準(zhǔn)坐標(biāo)系;
2. gcj02:經(jīng)過國(guó)測(cè)局加密的坐標(biāo);
3. bd09:為百度坐標(biāo)系,其中bd09ll表示百度經(jīng)緯度坐標(biāo),bd09mc表示百度墨卡托米制坐標(biāo);
* 在國(guó)內(nèi)獲得的坐標(biāo)系類型可以是:國(guó)測(cè)局坐標(biāo)、百度墨卡托坐標(biāo) 和 百度經(jīng)緯度坐標(biāo)。
  在海外地區(qū),只能獲得WGS84坐標(biāo)。請(qǐng)?jiān)谑褂眠^程中注意選擇坐標(biāo)。
*/
mOption.setCoorType("bd09ll");

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

/**
* 默認(rèn)false,設(shè)置是否需要地址信息
* 返回省、市、區(qū)、街道等地址信息,這個(gè)api用處很大,
  很多新聞?lì)恆pp會(huì)根據(jù)定位返回的市區(qū)信息推送用戶所在市的新聞
*/
mOption.setIsNeedAddress(true);

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

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

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

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

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

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

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

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

3. 發(fā)起定位

發(fā)起定位,便能夠從BDAbstractLocationListener監(jiān)聽接口中獲取定位結(jié)果信息。

//mLocationClient為第二步初始化過的LocationClient對(duì)象
//調(diào)用LocationClient的start()方法,便可發(fā)起定位請(qǐng)求
mLocationClient.start();
//tart():?jiǎn)?dòng)定位SDK;stop():關(guān)閉定位SDK。調(diào)用start()之后只需要等待定位結(jié)果自動(dòng)回調(diào)即可。
//開發(fā)者定位場(chǎng)景如果是單次定位的場(chǎng)景,在收到定位結(jié)果之后直接調(diào)用stop()函數(shù)即可。
//如果stop()之后仍然想進(jìn)行定位,可以再次start()等待定位結(jié)果回調(diào)即可。
//自v7.2版本起,新增LocationClient.reStart()方法,用于在某些特定的異常環(huán)境下重啟定位。

4.實(shí)現(xiàn)BDAbstractLocationListener接口

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

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

4.1 獲取基本定位信息

bdLocation.getLatitude();//緯度
bdLocation.getLongitude();//經(jīng)度
bdLocation.getDirection();//定位方向
bdLocation.getRadius();//定位精度
bdLocation.getCoorType();//定位坐標(biāo)類型
bdLocation.getLocType();//定位類型、定位錯(cuò)誤返回碼
bdLocation.getLocTypeDescription();//對(duì)應(yīng)的定位類型說明
bdLocation.getTime();//獲取經(jīng)緯度服務(wù)器時(shí)間
//判斷用戶是在室內(nèi),還是在室外1:室內(nèi),0:室外,這個(gè)判斷不一定是100%準(zhǔn)確的
bdLocation.getUserIndoorState();

4.2 獲取地址信息

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

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

4.3 獲取位置信息描述

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

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

4.4 周邊POI信息

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

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

4.5 判斷定位類型

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

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

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

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

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

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

4.6 國(guó)內(nèi)外位置判斷

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

4.7 位置提醒

定位SDK支持位置提醒功能,位置提醒最多提醒3次,3次過后將不再提醒。假如需要再次提醒、或者要修改提醒點(diǎn)坐標(biāo),都可通過函數(shù)SetNotifyLocation()來(lái)實(shí)現(xiàn)。

4.7.1 注冊(cè)監(jiān)聽函數(shù)

 //注冊(cè)監(jiān)聽函數(shù)
 mLocationClient.registerNotify(myListener);    

4.7.2 實(shí)現(xiàn)位置監(jiān)聽的回調(diào)

定義MyNotifyLister類,繼承BDNotifyListener,實(shí)現(xiàn)位置監(jiān)聽的回調(diào)。
public class MyNotifyLister extends BDNotifyListener {
    public void onNotify(BDLocation mlocation, float distance){
        //已到達(dá)設(shè)置監(jiān)聽位置附近
    }           
}

4.7.3 實(shí)現(xiàn)設(shè)置位置消息提醒

調(diào)用BDNotifyListener的setNotifyLocation方法,實(shí)現(xiàn)設(shè)置位置消息提醒。
myListener.setNotifyLocation(40.0f, 116.0f, 3000, mLocationClient.getLocOption().getCoorType());
//設(shè)置位置提醒,四個(gè)參數(shù)分別是:緯度,經(jīng)度,距離范圍,坐標(biāo)系類型(gcj02,gps,bd09,bd09ll)

4.7.4 啟動(dòng)定位

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

4.7.5 取消監(jiān)聽

調(diào)用BDNotifyListener的removeNotifyEvent方法,實(shí)現(xiàn)取消位置監(jiān)聽。核心代碼如下:
myListener.removeNotifyEvent(myListener);
//myListener為第二步中定義過的BDNotifyListener對(duì)象
//調(diào)用執(zhí)行removeNotifyEvent方法,即可實(shí)現(xiàn)取消監(jiān)聽

5. 釋放資源

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

本文主要做于收集整理筆記使用,關(guān)于文章的源碼,請(qǐng)移步我的GitHub

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容