Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android百度地圖開發教程(二)定位功能介紹及地圖覆蓋物使用示例

Android百度地圖開發教程(二)定位功能介紹及地圖覆蓋物使用示例

編輯:Android開發實例

這一篇文章主要講解的是百度地圖的定位功能,然後還有MyLocationOverlay和PopupOverlay兩個地圖覆蓋物的使用,Overlay是“圖層”或“覆蓋物”的意思,MyLocationOverlay從名字上面理解就是我的位置圖層,他能夠實現在地圖上顯示當前位置的圖標以及指南針,MyLocationOverlay只負責顯示我的位置,位置數據請使用百度定位SDK獲取,將獲取的位置數據放在一個LocationData結構中並用該結構設置MyLcationOverlay的數據源,即可創建MyLocationOverlay,PopupOverlay就是彈出窗口圖層了,跟PopupWindow類似的東西,下面會介紹他們的使用方法
定位我們使用的是百度 Android 定位SDKv4.0,我們先了解下定位原理和定位精度


定位原理
使用百度Android定位SDK必須注冊GPS和網絡使用權限。定位SDK采用GPS、基站、Wi-Fi信號進行定位。當應用程序向定位SDK發起定位請求時,定位SDK會根據應用的定位因素(GPS、基站、Wi-Fi信號)的實際情況(如是否開啟GPS、是否連接網絡、是否有信號等)來生成相應定位依據進行定位。
用戶可以設置滿足自身需求的定位依據:
若用戶設置GPS優先,則優先使用GPS進行定位,如果GPS定位未打開或者沒有可用位置信息,且網絡連接正常,定位SDK則會返回網絡定位(即Wi-Fi與基站)的最優結果。為了使獲得的網絡定位結果更加精確,請打開手機的Wi-Fi開關。

 

 

定位精度

 

 

 


 


了解了百度定位的原理和定位精度之後,接下來我們就來使用百度定位SDKv4.0吧

 

一 . 導入庫文件

在使用百度定位SDKv4.0之前,我們要下載最新的庫文件,下載地址:點擊下載相關庫文件,將liblocSDK4.so文件拷貝到libs/armeabi目錄下。將locSDK4.0.jar文件拷貝到工程的libs目錄下

 


二 . 布局文件,一個百度地圖控件,加一個手動點擊實現定位的按鈕,放在一個相對布局裡面,很簡單的布局

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_width="fill_parent" 
  4.     android:layout_height="fill_parent" > 
  5.  
  6.     <com.baidu.mapapi.map.MapView 
  7.         android:id="@+id/bmapView" 
  8.         android:layout_width="fill_parent" 
  9.         android:layout_height="fill_parent" 
  10.         android:clickable="true" /> 
  11.       
  12.       
  13.      <Button 
  14.          android:id="@+id/request" 
  15.          android:layout_width="wrap_content" 
  16.          android:layout_height="wrap_content" 
  17.          android:layout_alignParentRight="true" 
  18.          android:layout_alignParentTop="true" 
  19.          android:layout_marginRight="10dp" 
  20.          android:layout_marginTop="10dip" 
  21.          android:background="@drawable/custom_loc"  /> 
  22.  
  23. </RelativeLayout> 

三 . 界面MainActivity代碼,先貼上,然後適當講解相關代碼,我注釋也比較清楚

  1. package com.example.baidumapdemo;  
  2.  
  3. import android.app.Activity;  
  4. import android.graphics.Bitmap;  
  5. import android.os.Bundle;  
  6. import android.util.Log;  
  7. import android.view.LayoutInflater;  
  8. import android.view.View;  
  9. import android.view.View.MeasureSpec;  
  10. import android.view.View.OnClickListener;  
  11. import android.widget.Button;  
  12. import android.widget.TextView;  
  13. import android.widget.Toast;  
  14.  
  15. import com.baidu.location.BDLocation;  
  16. import com.baidu.location.BDLocationListener;  
  17. import com.baidu.location.LocationClient;  
  18. import com.baidu.location.LocationClientOption;  
  19. import com.baidu.mapapi.BMapManager;  
  20. import com.baidu.mapapi.MKGeneralListener;  
  21. import com.baidu.mapapi.map.LocationData;  
  22. import com.baidu.mapapi.map.MKEvent;  
  23. import com.baidu.mapapi.map.MapController;  
  24. import com.baidu.mapapi.map.MapView;  
  25. import com.baidu.mapapi.map.MyLocationOverlay;  
  26. import com.baidu.mapapi.map.PopupClickListener;  
  27. import com.baidu.mapapi.map.PopupOverlay;  
  28. import com.baidu.platform.comapi.basestruct.GeoPoint;  
  29.  
  30. public class MainActivity extends Activity {  
  31.     private Toast mToast;  
  32.     private BMapManager mBMapManager;  
  33.     private MapView mMapView = null;  
  34.     private MapController mMapController = null;  
  35.       
  36.     /**  
  37.      * 定位SDK的核心類  
  38.      */ 
  39.     private LocationClient mLocClient;  
  40.     /**  
  41.      * 用戶位置信息   
  42.      */ 
  43.     private LocationData mLocData;  
  44.     /**  
  45.      * 我的位置圖層  
  46.      */ 
  47.     private LocationOverlay myLocationOverlay = null;  
  48.     /**  
  49.      * 彈出窗口圖層  
  50.      */ 
  51.     private PopupOverlay mPopupOverlay  = null;  
  52.       
  53.     private boolean isRequest = false;//是否手動觸發請求定位  
  54.     private boolean isFirstLoc = true;//是否首次定位  
  55.       
  56.     /**  
  57.      * 彈出窗口圖層的View  
  58.      */ 
  59.     private View mPopupView;  
  60.     private BDLocation location;  
  61.  
  62.     @Override 
  63.     protected void onCreate(Bundle savedInstanceState) {  
  64.         super.onCreate(savedInstanceState);  
  65.         //使用地圖sdk前需先初始化BMapManager,這個必須在setContentView()先初始化  
  66.         mBMapManager = new BMapManager(this);  
  67.           
  68.         //第一個參數是API key,  
  69.         //第二個參數是常用事件監聽,用來處理通常的網絡錯誤,授權驗證錯誤等,你也可以不添加這個回調接口  
  70.         mBMapManager.init("7ae13368159d6a513eaa7a17b9413b4b", new MKGeneralListenerImpl());  
  71.         setContentView(R.layout.activity_main);  
  72.           
  73.         //點擊按鈕手動請求定位  
  74.         ((Button) findViewById(R.id.request)).setOnClickListener(new OnClickListener() {  
  75.               
  76.             @Override 
  77.             public void onClick(View v) {  
  78.                 requestLocation();  
  79.             }  
  80.         });  
  81.           
  82.         mMapView = (MapView) findViewById(R.id.bmapView); //獲取百度地圖控件實例  
  83.         mMapController = mMapView.getController(); //獲取地圖控制器  
  84.         mMapController.enableClick(true);   //設置地圖是否響應點擊事件  
  85.         mMapController.setZoom(14);   //設置地圖縮放級別  
  86.         mMapView.setBuiltInZoomControls(true);   //顯示內置縮放控件  
  87.           
  88.         mMapView.setTraffic(true);  //設置交通信息圖  
  89. //        mMapView.setSatellite(true);  //設置衛星圖  
  90. //        mMapController.setOverlooking(-45);  //設置地圖俯視角度 ,范圍:0~ -45  
  91.           
  92.           
  93.         mPopupView = LayoutInflater.from(this).inflate(R.layout.pop_layout, null);  
  94.           
  95.         //實例化彈出窗口圖層  
  96.         mPopupOverlay = new PopupOverlay(mMapView ,new PopupClickListener() {  
  97.               
  98.             /**  
  99.              * 點擊彈出窗口圖層回調的方法  
  100.              */ 
  101.             @Override 
  102.             public void onClickedPopup(int arg0) {  
  103.                 //隱藏彈出窗口圖層  
  104.                 mPopupOverlay.hidePop();  
  105.             }  
  106.         });  
  107.           
  108.           
  109.         //實例化定位服務,LocationClient類必須在主線程中聲明  
  110.         mLocClient = new LocationClient(getApplicationContext());  
  111.         mLocClient.registerLocationListener(new BDLocationListenerImpl());//注冊定位監聽接口  
  112.           
  113.         /**  
  114.          * LocationClientOption 該類用來設置定位SDK的定位方式。  
  115.          */ 
  116.         LocationClientOption option = new LocationClientOption();  
  117.         option.setOpenGps(true); //打開GPRS  
  118.         option.setAddrType("all");//返回的定位結果包含地址信息  
  119.         option.setCoorType("bd09ll");//返回的定位結果是百度經緯度,默認值gcj02  
  120.         option.setPriority(LocationClientOption.GpsFirst); // 設置GPS優先  
  121.         option.setScanSpan(5000); //設置發起定位請求的間隔時間為5000ms  
  122.         option.disableCache(false);//禁止啟用緩存定位  
  123. //      option.setPoiNumber(5);    //最多返回POI個數     
  124. //      option.setPoiDistance(1000); //poi查詢距離          
  125. //      option.setPoiExtraInfo(true);  //是否需要POI的電話和地址等詳細信息          
  126.         mLocClient.setLocOption(option);  //設置定位參數  
  127.           
  128.           
  129.         mLocClient.start();  // 調用此方法開始定位  
  130.           
  131.         //定位圖層初始化  
  132.         myLocationOverlay = new LocationOverlay(mMapView);  
  133.           
  134.           
  135.         //實例化定位數據,並設置在我的位置圖層  
  136.         mLocData = new LocationData();  
  137.         myLocationOverlay.setData(mLocData);  
  138.           
  139.         //添加定位圖層  
  140.         mMapView.getOverlays().add(myLocationOverlay);  
  141.           
  142.         //修改定位數據後刷新圖層生效  
  143.         mMapView.refresh();  
  144.           
  145.           
  146.     }  
  147.       
  148.       
  149.     /**  
  150.      * 定位接口,需要實現兩個方法  
  151.      * @author xiaanming  
  152.      *  
  153.      */ 
  154.     public class BDLocationListenerImpl implements BDLocationListener {  
  155.  
  156.         /**  
  157.          * 接收異步返回的定位結果,參數是BDLocation類型參數  
  158.          */ 
  159.         @Override 
  160.         public void onReceiveLocation(BDLocation location) {  
  161.             if (location == null) {  
  162.                 return;  
  163.             }  
  164.               
  165.             StringBuffer sb = new StringBuffer(256);  
  166.               sb.append("time : ");  
  167.               sb.append(location.getTime());  
  168.               sb.append("\nerror code : ");  
  169.               sb.append(location.getLocType());  
  170.               sb.append("\nlatitude : ");  
  171.               sb.append(location.getLatitude());  
  172.               sb.append("\nlontitude : ");  
  173.               sb.append(location.getLongitude());  
  174.               sb.append("\nradius : ");  
  175.               sb.append(location.getRadius());  
  176.               if (location.getLocType() == BDLocation.TypeGpsLocation){  
  177.                    sb.append("\nspeed : ");  
  178.                    sb.append(location.getSpeed());  
  179.                    sb.append("\nsatellite : ");  
  180.                    sb.append(location.getSatelliteNumber());  
  181.                    } else if (location.getLocType() == BDLocation.TypeNetWorkLocation){  
  182.                    sb.append("\naddr : ");  
  183.                    sb.append(location.getAddrStr());  
  184.                 }   
  185.            
  186.               Log.e("log", sb.toString());  
  187.               
  188.               
  189.             MainActivity.this.location = location;  
  190.               
  191.             mLocData.latitude = location.getLatitude();  
  192.             mLocData.longitude = location.getLongitude();  
  193.             //如果不顯示定位精度圈,將accuracy賦值為0即可  
  194.             mLocData.accuracy = location.getRadius();  
  195.             mLocData.direction = location.getDerect();  
  196.               
  197.             //將定位數據設置到定位圖層裡  
  198.             myLocationOverlay.setData(mLocData);  
  199.             //更新圖層數據執行刷新後生效  
  200.             mMapView.refresh();  
  201.               
  202.               
  203.             if(isFirstLoc || isRequest){  
  204.                 //將給定的位置點以動畫形式移動至地圖中心  
  205.                 mMapController.animateTo(new GeoPoint(  
  206.                         (int) (location.getLatitude() * 1e6), (int) (location  
  207.                                 .getLongitude() * 1e6)));  
  208.                 showPopupOverlay(location);  
  209.                 isRequest = false;  
  210.             }  
  211.             isFirstLoc = false;  
  212.               
  213.         }  
  214.  
  215.         /**  
  216.          * 接收異步返回的POI查詢結果,參數是BDLocation類型參數  
  217.          */ 
  218.         @Override 
  219.         public void onReceivePoi(BDLocation poiLocation) {  
  220.               
  221.         }  
  222.  
  223.     }  
  224.       
  225.       
  226.  
  227.     //繼承MyLocationOverlay重寫dispatchTap方法  
  228.     private class LocationOverlay extends MyLocationOverlay{  
  229.  
  230.         public LocationOverlay(MapView arg0) {  
  231.             super(arg0);  
  232.         }  
  233.  
  234.           
  235.         /**  
  236.          * 在“我的位置”坐標上處理點擊事件。  
  237.          */ 
  238.         @Override 
  239.         protected boolean dispatchTap() {  
  240.             //點擊我的位置顯示PopupOverlay  
  241.             showPopupOverlay(location);  
  242.             return super.dispatchTap();  
  243.         }  
  244.           
  245.     }  
  246.       
  247.       
  248.     /**  
  249.      * 顯示彈出窗口圖層PopupOverlay  
  250.      * @param location  
  251.      */ 
  252.     private void showPopupOverlay(BDLocation location){  
  253.          TextView popText = ((TextView)mPopupView.findViewById(R.id.location_tips));  
  254.          popText.setText("[我的位置]\n" + location.getAddrStr());  
  255.          mPopupOverlay.showPopup(getBitmapFromView(popText),  
  256.                     new GeoPoint((int)(location.getLatitude()*1e6), (int)(location.getLongitude()*1e6)),  
  257.                     15);  
  258.            
  259.     }  
  260.       
  261.       
  262.     /**  
  263.      * 手動請求定位的方法  
  264.      */ 
  265.     public void requestLocation() {  
  266.         isRequest = true;  
  267.           
  268.         if(mLocClient != null && mLocClient.isStarted()){  
  269.             showToast("正在定位......");  
  270.             mLocClient.requestLocation();  
  271.         }else{  
  272.             Log.d("log", "locClient is null or not started");  
  273.         }  
  274.     }  
  275.       
  276.       
  277.       
  278.      /**   
  279.      * 顯示Toast消息   
  280.      * @param msg   
  281.      */    
  282.     private void showToast(String msg){    
  283.         if(mToast == null){    
  284.             mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);    
  285.         }else{    
  286.             mToast.setText(msg);    
  287.             mToast.setDuration(Toast.LENGTH_SHORT);  
  288.         }    
  289.         mToast.show();    
  290.     }   
  291.       
  292.     /**  
  293.      * 將View轉換成Bitmap的方法  
  294.      * @param view  
  295.      * @return  
  296.      */ 
  297.     public static Bitmap getBitmapFromView(View view) {  
  298.         view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));  
  299.         view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());  
  300.         view.buildDrawingCache();  
  301.         Bitmap bitmap = view.getDrawingCache();  
  302.         return bitmap;  
  303.     }  
  304.       
  305.       
  306.       
  307.       
  308.       
  309.     /**  
  310.      * 常用事件監聽,用來處理通常的網絡錯誤,授權驗證錯誤等  
  311.      * @author xiaanming  
  312.      *  
  313.      */ 
  314.     public class MKGeneralListenerImpl implements MKGeneralListener{  
  315.  
  316.         /**  
  317.          * 一些網絡狀態的錯誤處理回調函數  
  318.          */ 
  319.         @Override 
  320.         public void onGetNetworkState(int iError) {  
  321.             if (iError == MKEvent.ERROR_NETWORK_CONNECT) {  
  322.                 showToast("您的網絡出錯啦!");  
  323.             }  
  324.         }  
  325.  
  326.         /**  
  327.          * 授權錯誤的時候調用的回調函數  
  328.          */ 
  329.         @Override 
  330.         public void onGetPermissionState(int iError) {  
  331.             if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) {  
  332.                 showToast("API KEY錯誤, 請檢查!");  
  333.             }  
  334.         }  
  335.           
  336.     }  
  337.       
  338.     @Override 
  339.     protected void onResume() {  
  340.         //MapView的生命周期與Activity同步,當activity掛起時需調用MapView.onPause()  
  341.         mMapView.onResume();  
  342.         super.onResume();  
  343.     }  
  344.  
  345.  
  346.  
  347.     @Override 
  348.     protected void onPause() {  
  349.         //MapView的生命周期與Activity同步,當activity掛起時需調用MapView.onPause()  
  350.         mMapView.onPause();  
  351.         super.onPause();  
  352.     }  
  353.  
  354.     @Override 
  355.     protected void onDestroy() {  
  356.         //MapView的生命周期與Activity同步,當activity銷毀時需調用MapView.destroy()  
  357.         mMapView.destroy();  
  358.           
  359.         //退出應用調用BMapManager的destroy()方法  
  360.         if(mBMapManager != null){  
  361.             mBMapManager.destroy();  
  362.             mBMapManager = null;  
  363.         }  
  364.           
  365.         //退出時銷毀定位  
  366.         if (mLocClient != null){  
  367.             mLocClient.stop();  
  368.         }  
  369.           
  370.         super.onDestroy();  
  371.     }  
  372.  
  373.       
  374.       

LocationClient 定位SDK的核心類,LocationClient類必須在主線程中聲明。需要Context類型的參數。Context需要時全進程有效的context,推薦用getApplicationConext獲取全進程有效的context,我們調用registerLocationListener(BDLocationListener)方法來注冊定位監聽接口,BDLocationListener裡面有兩個方法,onReceiveLocation()(接收異步返回的定位結果),onReceivePoi()(接收異步返回的POI查詢結果,POI是“Point of Interest”的縮寫,可以翻譯成“信息點”,每個POI包含四方面信息,名稱、類別、經度、緯度、附近的酒店、飯店,商鋪等信息。我們可以叫它為“導航地圖信息”,導航地圖數據是整個導航產業的基石),我們這裡只需要重寫onReceiveLocation就行了
BDLocation 封裝了定位SDK的定位結果,在BDLocationListener的onReceive方法中獲取。通過該類用戶可以獲取error code,位置的坐標,精度半徑,地址等信息,對於其getLocType ()方法獲取的error code一些情況

  1. 61 : GPS定位結果
  2. 62 : 掃描整合定位依據失敗。此時定位結果無效。
  3. 63 : 網絡異常,沒有成功向服務器發起請求。此時定位結果無效。
  4. 65 : 定位緩存的結果。
  5. 66 : 離線定位結果。通過requestOfflineLocaiton調用時對應的返回結果
  6. 67 : 離線定位失敗。通過requestOfflineLocaiton調用時對應的返回結果
  7. 68 : 網絡連接失敗時,查找本地離線定位時對應的返回結果
  8. 161: 表示網絡定位結果
  9. 162~167: 服務端定位失敗
  10. LocationClientOption 用來設置定位SDK的定位方式,比如設置打開GPS,設置是否需要地址信息,設置發起定位請求的間隔時間等等,參數設置完後調用LocationClient 的setLocOption方法
  • LocationOverlay MyLocationOverlay的子類,重寫裡面的dispatchTap()方法,顯示彈出窗口圖層PopupOverlay,調用mMapView.getOverlays().add(myLocationOverlay)就將我的位置圖層添加到地圖裡面
  • PopupOverlay 彈出圖層,這個類還是比較簡單,裡面只有三個方法,hidePop() (隱藏彈出圖層)showPopup(Bitmap pop, GeoPoint point, int yOffset) (顯示彈出圖層)和showPopup顯示多張圖片的重載方法,由於showPopup方法只接受Bitmap對象,所以我們必須將我們的彈出圖層View對象轉換成Bitmap對象,我們調用getBitmapFromView方法就實現這一轉換
  • BDLocationListener接口的onReceiveLocation(BDLocation location) 方法我還要重點講解下,我們會發現onReceiveLocation方法會反復執行,他執行的間隔跟LocationClientOption類的setScanSpan()方法設定的值有關,我們設定的是5000毫秒,則onReceiveLocation方法每隔5秒執行一次,注意,當我們設定的值大於1000(ms),定位SDK內部使用定時定位模式。調用requestLocation( )後,每隔設定的時間,定位SDK就會進行一次定位。如果定位SDK根據定位依據發現位置沒有發生變化,就不會發起網絡請求,返回上一次定位的結果;如果發現位置改變,就進行網絡請求進行定位,得到新的定位結果。如果你只需要定位一次的話,這個設置小於1000,或者不用設置就可以了,定時定位時,調用一次requestLocation,會定時監聽到定位結果
     

四 . 在運行程序之前,我們還必須在AndroidManifest.xml進行相關配置和權限的聲明
在application標簽中聲明service組件,每個app擁有自己單獨的定位service

  1. <service 
  2.             android:name="com.baidu.location.f" 
  3.             android:enabled="true" 
  4.             android:process=":remote" > 
  5.         </service> 

聲明相關的使用權限

  1. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
  2. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
  3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
  4. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
  5. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
  6. <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
  7. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
  8. <uses-permission android:name="android.permission.INTERNET" /> 
  9. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> 
  10. <uses-permission android:name="android.permission.READ_LOGS" /> 

五 . 運行結果
 

源碼下載

轉自:http://blog. csdn. net/xiaanming/article/details/11380619

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved