Android 百度地圖開發之MyLocationOverlay,PopupOverlay的使用

這一篇文章主要講解的是百度地圖的定位功能,而後還有MyLocationOverlay和PopupOverlay兩個地圖覆蓋物的使用,Overlay是「圖層」或「覆蓋物」的意思,MyLocationOverlay從名字上面理解就是個人位置圖層,他可以實如今地圖上顯示當前位置的圖標以及指南針,MyLocationOverlay只負責顯示個人位置,位置數據請使用百度定位SDK獲取,將獲取的位置數據放在一個LocationData結構中並用該結構設置MyLcationOverlay的數據源,便可建立MyLocationOverlay,PopupOverlay就是彈出窗口圖層了,跟PopupWindow相似的東西,下面會介紹他們的使用方法 html


定位咱們使用的是百度 Android 定位SDKv4.0,咱們先了解下定位原理和定位精度 java


定位原理 android

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



定位精度 api


瞭解了百度定位的原理和定位精度以後,接下來咱們就來使用百度定位SDKv4.0吧 緩存


一 . 導入庫文件 服務器

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


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

  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>  
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true" />
    
    
     <Button
         android:id="@+id/request"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentRight="true"
         android:layout_alignParentTop="true"
         android:layout_marginRight="10dp"
         android:layout_marginTop="10dip"
         android:background="@drawable/custom_loc"  />

</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(00, 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.       
  375. }  
package com.example.baidumapdemo;

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.LocationData;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationOverlay;
import com.baidu.mapapi.map.PopupClickListener;
import com.baidu.mapapi.map.PopupOverlay;
import com.baidu.platform.comapi.basestruct.GeoPoint;

public class MainActivity extends Activity {
	private Toast mToast;
	private BMapManager mBMapManager;
	private MapView mMapView = null;
	private MapController mMapController = null;
	
	/**
	 * 定位SDK的核心類
	 */
	private LocationClient mLocClient;
	/**
	 * 用戶位置信息 
	 */
	private LocationData mLocData;
	/**
	 * 個人位置圖層
	 */
	private	LocationOverlay myLocationOverlay = null;
	/**
	 * 彈出窗口圖層
	 */
	private PopupOverlay mPopupOverlay  = null;
	
	private boolean isRequest = false;//是否手動觸發請求定位
	private boolean isFirstLoc = true;//是否首次定位
	
	/**
	 * 彈出窗口圖層的View
	 */
	private View mPopupView;
	private BDLocation location;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//使用地圖sdk前需先初始化BMapManager,這個必須在setContentView()先初始化
		mBMapManager = new BMapManager(this);
		
		//第一個參數是API key,
		//第二個參數是經常使用事件監聽,用來處理一般的網絡錯誤,受權驗證錯誤等,你也能夠不添加這個回調接口
		mBMapManager.init("7ae13368159d6a513eaa7a17b9413b4b", new MKGeneralListenerImpl());
		setContentView(R.layout.activity_main);
		
		//點擊按鈕手動請求定位
		((Button) findViewById(R.id.request)).setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				requestLocation();
			}
		});
		
		mMapView = (MapView) findViewById(R.id.bmapView); //獲取百度地圖控件實例
        mMapController = mMapView.getController(); //獲取地圖控制器
        mMapController.enableClick(true);   //設置地圖是否響應點擊事件
        mMapController.setZoom(14);   //設置地圖縮放級別
        mMapView.setBuiltInZoomControls(true);   //顯示內置縮放控件
        
        mMapView.setTraffic(true);  //設置交通訊息圖
//        mMapView.setSatellite(true);  //設置衛星圖
//        mMapController.setOverlooking(-45);  //設置地圖俯視角度 ,範圍:0~ -45
        
        
        mPopupView = LayoutInflater.from(this).inflate(R.layout.pop_layout, null);
        
        //實例化彈出窗口圖層
        mPopupOverlay = new PopupOverlay(mMapView ,new PopupClickListener() {
			
        	/**
        	 * 點擊彈出窗口圖層回調的方法
        	 */
			@Override
			public void onClickedPopup(int arg0) {
				//隱藏彈出窗口圖層
				mPopupOverlay.hidePop();
			}
		});
        
        
        //實例化定位服務,LocationClient類必須在主線程中聲明
        mLocClient = new LocationClient(getApplicationContext());
		mLocClient.registerLocationListener(new BDLocationListenerImpl());//註冊定位監聽接口
		
		/**
		 * LocationClientOption 該類用來設置定位SDK的定位方式。
		 */
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true); //打開GPRS
		option.setAddrType("all");//返回的定位結果包含地址信息
		option.setCoorType("bd09ll");//返回的定位結果是百度經緯度,默認值gcj02
		option.setPriority(LocationClientOption.GpsFirst); // 設置GPS優先
		option.setScanSpan(5000); //設置發起定位請求的間隔時間爲5000ms
		option.disableCache(false);//禁止啓用緩存定位
//		option.setPoiNumber(5);    //最多返回POI個數   
//		option.setPoiDistance(1000); //poi查詢距離        
//		option.setPoiExtraInfo(true);  //是否須要POI的電話和地址等詳細信息        
		mLocClient.setLocOption(option);  //設置定位參數
		
		
		mLocClient.start();  //	調用此方法開始定位
		
		//定位圖層初始化
		myLocationOverlay = new LocationOverlay(mMapView);
		
		
		//實例化定位數據,並設置在個人位置圖層
        mLocData = new LocationData();
	    myLocationOverlay.setData(mLocData);
	    
	    //添加定位圖層
	    mMapView.getOverlays().add(myLocationOverlay);
	    
	    //修改定位數據後刷新圖層生效
	    mMapView.refresh();
		
		
	}
	
	
	/**
	 * 定位接口,須要實現兩個方法
	 * @author xiaanming
	 *
	 */
	public class BDLocationListenerImpl implements BDLocationListener {

		/**
		 * 接收異步返回的定位結果,參數是BDLocation類型參數
		 */
		@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());
		        } 
		 
		      Log.e("log", sb.toString());
			
			
			MainActivity.this.location = location;
			
			mLocData.latitude = location.getLatitude();
			mLocData.longitude = location.getLongitude();
			//若是不顯示定位精度圈,將accuracy賦值爲0便可
			mLocData.accuracy = location.getRadius();
			mLocData.direction = location.getDerect();
			
			//將定位數據設置到定位圖層裏
            myLocationOverlay.setData(mLocData);
            //更新圖層數據執行刷新後生效
            mMapView.refresh();
            
			
            if(isFirstLoc || isRequest){
            	//將給定的位置點以動畫形式移動至地圖中心
				mMapController.animateTo(new GeoPoint(
						(int) (location.getLatitude() * 1e6), (int) (location
								.getLongitude() * 1e6)));
				showPopupOverlay(location);
				isRequest = false;
            }
            isFirstLoc = false;
            
		}

		/**
		 * 接收異步返回的POI查詢結果,參數是BDLocation類型參數
		 */
		@Override
		public void onReceivePoi(BDLocation poiLocation) {
			
		}

	}
	
	

	//繼承MyLocationOverlay重寫dispatchTap方法
	private class LocationOverlay extends MyLocationOverlay{

		public LocationOverlay(MapView arg0) {
			super(arg0);
		}

		
		/**
		 * 在「個人位置」座標上處理點擊事件。
		 */
		@Override
		protected boolean dispatchTap() {
			//點擊個人位置顯示PopupOverlay
			showPopupOverlay(location);
			return super.dispatchTap();
		}
		
	}
	
	
	/**
	 * 顯示彈出窗口圖層PopupOverlay
	 * @param location
	 */
	private void showPopupOverlay(BDLocation location){
		 TextView popText = ((TextView)mPopupView.findViewById(R.id.location_tips));
		 popText.setText("[個人位置]\n" + location.getAddrStr());
		 mPopupOverlay.showPopup(getBitmapFromView(popText),
					new GeoPoint((int)(location.getLatitude()*1e6), (int)(location.getLongitude()*1e6)),
					15);
		 
	}
	
	
	/**
	 * 手動請求定位的方法
	 */
	public void requestLocation() {
		isRequest = true;
		
		if(mLocClient != null && mLocClient.isStarted()){
			showToast("正在定位......");
			mLocClient.requestLocation();
		}else{
			Log.d("log", "locClient is null or not started");
		}
	}
	
	
	
	 /** 
     * 顯示Toast消息 
     * @param msg 
     */  
    private void showToast(String msg){  
        if(mToast == null){  
            mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);  
        }else{  
            mToast.setText(msg);  
            mToast.setDuration(Toast.LENGTH_SHORT);
        }  
        mToast.show();  
    } 
	
	/**
	 * 將View轉換成Bitmap的方法
	 * @param view
	 * @return
	 */
	public static Bitmap getBitmapFromView(View view) {
		view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        return bitmap;
	}
	
	
	
	
	
	/**
	 * 經常使用事件監聽,用來處理一般的網絡錯誤,受權驗證錯誤等
	 * @author xiaanming
	 *
	 */
	public class MKGeneralListenerImpl implements MKGeneralListener{

		/**
		 * 一些網絡狀態的錯誤處理回調函數
		 */
		@Override
		public void onGetNetworkState(int iError) {
			if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
				showToast("您的網絡出錯啦!");
            }
		}

		/**
		 * 受權錯誤的時候調用的回調函數
		 */
		@Override
		public void onGetPermissionState(int iError) {
			if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) {
				showToast("API KEY錯誤, 請檢查!");
            }
		}
		
	}
	
	@Override
	protected void onResume() {
    	//MapView的生命週期與Activity同步,當activity掛起時需調用MapView.onPause()
		mMapView.onResume();
		super.onResume();
	}



	@Override
	protected void onPause() {
		//MapView的生命週期與Activity同步,當activity掛起時需調用MapView.onPause()
		mMapView.onPause();
		super.onPause();
	}

	@Override
	protected void onDestroy() {
		//MapView的生命週期與Activity同步,當activity銷燬時需調用MapView.destroy()
		mMapView.destroy();
		
		//退出應用調用BMapManager的destroy()方法
		if(mBMapManager != null){
			mBMapManager.destroy();
			mBMapManager = null;
		}
		
		//退出時銷燬定位
        if (mLocClient != null){
            mLocClient.stop();
        }
		
		super.onDestroy();
	}

	
	
}
  • 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: 服務端定位失敗
  • 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>  
<service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" >
        </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" />  
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.READ_LOGS" />

五 . 運行結果


今天的講解到此結束,有疑問的朋友請在下面留言。以後會持續介紹百度地圖的使用,歡迎你們關注!
相關文章
相關標籤/搜索