重拾百度定位之踩坑篇(下)
接上文
實(shí)現(xiàn)BDLocationListener接口
- /*****
- * 定位結(jié)果回調(diào),重寫(xiě)onReceiveLocation方法
- *
- */
- private BDLocationListener mListener = new BDLocationListener() {
- @Override
- public void onReceiveLocation(BDLocation location) {
- // TODO Auto-generated method stub
- if (null != location ) {
- StringBuffer sb = new StringBuffer(256);
- sb.append("time : ");
- /**
- * 時(shí)間也可以使用systemClock.elapsedRealtime()方法 獲取的是自從開(kāi)機(jī)以來(lái),每次回調(diào)的時(shí)間;
- * location.getTime() 是指服務(wù)端出本次結(jié)果的時(shí)間,如果位置不發(fā)生變化,則時(shí)間不變
- */
- sb.append(location.getTime());
- sb.append("\nlocType : ");// 定位類(lèi)型
- sb.append(location.getLocType());
- sb.append("\nlocType description : ");// *****對(duì)應(yīng)的定位類(lèi)型說(shuō)明*****
- //sb.append(location.getLocTypeDescription());
- sb.append("\nlatitude : ");// 緯度
- sb.append(location.getLatitude());
- sb.append("\nlontitude : ");// 經(jīng)度
- sb.append(location.getLongitude());
- sb.append("\nradius : ");// 半徑
- sb.append(location.getRadius());
- sb.append("\nCountryCode : ");// 國(guó)家碼
- sb.append(location.getCountryCode());
- sb.append("\nCountry : ");// 國(guó)家名稱(chēng)
- sb.append(location.getCountry());
- sb.append("\ncitycode : ");// 城市編碼
- sb.append(location.getCityCode());
- sb.append("\ncity : ");// 城市
- sb.append(location.getCity());
- sb.append("\nDistrict : ");// 區(qū)
- sb.append(location.getDistrict());
- sb.append("\nStreet : ");// 街道
- sb.append(location.getStreet());
- sb.append("\naddr : ");// 地址信息
- sb.append(location.getAddrStr());
- sb.append("\nUserIndoorState: ");// *****返回用戶(hù)室內(nèi)外判斷結(jié)果*****
- //sb.append(location.getUserIndoorState());
- sb.append("\nDirection(not all devices have value): ");
- sb.append(location.getDirection());// 方向
- sb.append("\nlocationdescribe: ");
- sb.append(location.getLocationDescribe());// 位置語(yǔ)義化信息
- sb.append("\nPoi: ");// POI信息
- if (location.getPoiList() != null && !location.getPoiList().isEmpty()) {
- for (int i = 0; i append(poi.getName() + ";");
- }
- }
- if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位結(jié)果
- sb.append("\nspeed : ");
- sb.append(location.getSpeed());// 速度 單位:km/h
- sb.append("\nsatellite : ");
- sb.append(location.getSatelliteNumber());// 衛(wèi)星數(shù)目
- sb.append("\nheight : ");
- sb.append(location.getAltitude());// 海拔高度 單位:米
- sb.append("\ngps status : ");
- //sb.append(location.getGpsAccuracyStatus());// *****gps質(zhì)量判斷*****
- sb.append("\ndescribe : ");
- sb.append("gps定位成功");
- } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 網(wǎng)絡(luò)定位結(jié)果
- // 運(yùn)營(yíng)商信息
- if (location.hasAltitude()) {// *****如果有海拔高度*****
- sb.append("\nheight : ");
- sb.append(location.getAltitude());// 單位:米
- }
- sb.append("\noperationers : ");// 運(yùn)營(yíng)商信息
- sb.append(location.getOperators());
- sb.append("\ndescribe : ");
- sb.append("網(wǎng)絡(luò)定位成功");
- } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 離線(xiàn)定位結(jié)果
- sb.append("\ndescribe : ");
- sb.append("離線(xiàn)定位成功,離線(xiàn)定位結(jié)果也是有效的");
- } else if (location.getLocType() == BDLocation.TypeServerError) {
- sb.append("\ndescribe : ");
- sb.append("服務(wù)端網(wǎng)絡(luò)定位失敗,可以反饋IMEI號(hào)和大體定位時(shí)間到loc-bugs@baidu.com,會(huì)有人追查原因");
- } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
- sb.append("\ndescribe : ");
- sb.append("網(wǎng)絡(luò)不同導(dǎo)致定位失敗,請(qǐng)檢查網(wǎng)絡(luò)是否通暢");
- } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
- sb.append("\ndescribe : ");
- sb.append("無(wú)法獲取有效定位依據(jù)導(dǎo)致定位失敗,一般是由于手機(jī)的原因,處于飛行模式下一般會(huì)造成這種結(jié)果,可以試著重啟手機(jī)");
- }
- tv_location.setText(sb+"\n定位結(jié)束");
- locationService.stop();
- }else{
- tv_location.setText("\n定位失敗");
- }
- }
- };
通過(guò)上面的實(shí)現(xiàn)后,我們?cè)谙胍ㄎ坏牡胤阶?cè)下回調(diào),并調(diào)用start()方法即可以獲取位置了,我對(duì)注冊(cè)開(kāi)始暫停做了下簡(jiǎn)單封裝,具體代碼參考LocationService。如果要寫(xiě)的項(xiàng)目里也要把回調(diào)接口封裝,自定義一個(gè)接口回調(diào)返回定位后的詳細(xì)位置信息。到這里即可成功定位了,下面就開(kāi)始介紹下這個(gè)過(guò)程會(huì)出現(xiàn)的問(wèn)題。
定位問(wèn)題分析
在分析之前我們先看下百度定位返回的錯(cuò)誤碼,分析定位的問(wèn)題也就是分析出現(xiàn)錯(cuò)誤碼的原因。
- 獲取定位返回錯(cuò)誤碼::
- public int getLocType ( )
- 返回值:
- 61 : GPS定位結(jié)果,GPS定位成功。
- 62 : 無(wú)法獲取有效定位依據(jù),定位失敗,請(qǐng)檢查運(yùn)營(yíng)商網(wǎng)絡(luò)或者WiFi網(wǎng)絡(luò)是否正常開(kāi)啟,嘗試重新請(qǐng)求定位。
- 63 : 網(wǎng)絡(luò)異常,沒(méi)有成功向服務(wù)器發(fā)起請(qǐng)求,請(qǐng)確認(rèn)當(dāng)前測(cè)試手機(jī)網(wǎng)絡(luò)是否通暢,嘗試重新請(qǐng)求定位。
- 65 : 定位緩存的結(jié)果。
- 66 : 離線(xiàn)定位結(jié)果。通過(guò)requestOfflineLocaiton調(diào)用時(shí)對(duì)應(yīng)的返回結(jié)果。
- 67 : 離線(xiàn)定位失敗。通過(guò)requestOfflineLocaiton調(diào)用時(shí)對(duì)應(yīng)的返回結(jié)果。
- 68 : 網(wǎng)絡(luò)連接失敗時(shí),查找本地離線(xiàn)定位時(shí)對(duì)應(yīng)的返回結(jié)果。
- 161: 網(wǎng)絡(luò)定位結(jié)果,網(wǎng)絡(luò)定位成功。
- 162: 請(qǐng)求串密文解析失敗,一般是由于客戶(hù)端SO文件加載失敗造成,請(qǐng)嚴(yán)格參照開(kāi)發(fā)指南或demo開(kāi)發(fā),放入對(duì)應(yīng)SO文件。
- 167: 服務(wù)端定位失敗,請(qǐng)您檢查是否禁用獲取位置信息權(quán)限,嘗試重新請(qǐng)求定位。
- 502: AK參數(shù)錯(cuò)誤,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)AK。
- 505:AK不存在或者非法,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)AK。
- 601: AK服務(wù)被開(kāi)發(fā)者自己禁用,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)AK。
- 602: key mcode不匹配,您的AK配置過(guò)程中安全碼設(shè)置有問(wèn)題,請(qǐng)確保:SHA1正確,“;”分號(hào)是英文狀態(tài);且包名是您當(dāng)前運(yùn)行應(yīng)用的包名,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)AK。
- 501~700:AK驗(yàn)證失敗,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)AK。
其實(shí)知道上面錯(cuò)誤碼代表的含義后,我們就很快速的定位問(wèn)題出現(xiàn)地方。當(dāng)然有些時(shí)候不如此,可能需要走一些彎路。
505錯(cuò)誤
在我升級(jí)定位SDK版本后遇到得到就是這個(gè)問(wèn)題,沒(méi)有更改任何代碼但是就是一直返回錯(cuò)誤碼是505.通過(guò)上面錯(cuò)誤碼表我們看到時(shí)AK不存在或者非法,但是依然很糾結(jié),因?yàn)榇a時(shí)點(diǎn)兒也沒(méi)有改,只是替換了jar和.so文件為最新版就不能用了。定位一直返回505,最后在官網(wǎng)更新日志看到V7.0版本有一條記錄 是優(yōu)化、完善AK校驗(yàn)機(jī)制,充分保證開(kāi)發(fā)者合法權(quán)益,保證開(kāi)發(fā)者應(yīng)用的安全性。具體怎么優(yōu)化并沒(méi)有說(shuō)明。不過(guò)也能猜測(cè)應(yīng)該是SHA1的值問(wèn)題。我先將demo用的定位SDK用V6.2.2(項(xiàng)目中用的此版本),然后更改SHA1的值,不管怎么改依然能成功定位。但是更改為了V7.0版本發(fā)現(xiàn)SHA1的值并不能隨便改,只能是運(yùn)行程序用的key文件的SHA1的值,否則就出現(xiàn)505錯(cuò)誤。至此問(wèn)題解決。在V7.0之前版本雖說(shuō)讓填寫(xiě)SHA1的值,但是并沒(méi)有什么有效作用,在V7.0版本開(kāi)始加入了嚴(yán)格的校驗(yàn)。在這里提供一個(gè)軟件可以校驗(yàn)APK的SHA1值,他提供了SHA1的和AK的校驗(yàn)功能。
如上圖,這上面顯示的SHA1的值應(yīng)該和你開(kāi)發(fā)版或者發(fā)布版中至少其中的一個(gè)相同。否則V7.0定位就不會(huì)成功。校驗(yàn)工具百度網(wǎng)盤(pán)下載鏈接,提取碼:je4r。
162錯(cuò)誤
162錯(cuò)誤一般是.so文件加載失敗引起的。在AndroidStudio中.so文件的位置和Eclipse中的是不一樣的。默認(rèn)情況下,AndroidStudio中.so文件放在main目錄下,在該文件夾下創(chuàng)建jniLibs,然后將不同內(nèi)核的.so文件放到該文件夾下就可以了。當(dāng)然一些人延續(xù)了Eclipse位置,將.so文件放置在libs目錄下,如果此時(shí)沒(méi)有其他一些配置.so文件是不能加載的。此時(shí)再gradle文件加入下面代碼即可
- sourceSets {
- main {
- jniLibs.srcDirs = ['libs']
- }
- }
其實(shí)最多出現(xiàn)的問(wèn)題也就是這兩種情況。正常情況下百度定位成功返回的是161也就是網(wǎng)絡(luò)定位結(jié)果(如上圖),但是有時(shí)候無(wú)網(wǎng)絡(luò)會(huì)返回66機(jī)離線(xiàn)定位結(jié)果,離線(xiàn)定位是小區(qū)定位,需要手機(jī)手機(jī)中有SIM卡,否則不會(huì)返回66,你可以嘗試下,把手機(jī)調(diào)到飛行模式,發(fā)現(xiàn)離線(xiàn)定位會(huì)失敗。百度定位默認(rèn)GPS定位是關(guān)閉的,如果想用GPS定位可以通過(guò)下面代碼打開(kāi),
- locationClientOption.setOpenGps(true);
BDLocationListener只回調(diào)一次
對(duì)于很多剛接觸定位的人可能還會(huì)遇到一個(gè)問(wèn)題就是,為何多次調(diào)用start()方法但是BDLocationListener回調(diào)只執(zhí)行一次。每次只要程序剛啟動(dòng)時(shí)才能定位成功。之后再定位就沒(méi)有反應(yīng)了。如果你第一次遇到這個(gè)問(wèn)題,確實(shí)很棘手,不管怎么改定位相關(guān)的代碼,并不能解決問(wèn)題。其實(shí)此時(shí)只需要在清單文件加入下面代碼既可以解決BDLocationListener只會(huì)回調(diào)一次的問(wèn)題
- <service
- android:name="com.baidu.location.f"
- android:enabled="true"
- android:process=":remote" >
- </service>
好了,到此,本篇文章真的結(jié)束了,若文章有不足或者錯(cuò)誤的地方,歡迎指正,以防止給其他讀者錯(cuò)誤引導(dǎo)