Android 百度地圖定位(手動+自動)

近因爲項目須要,研究了下百度地圖定位,他們提供的實例基本都是用監聽器實現自動定位的。我想實現一種效果:當用戶進入UI時,不定位,用戶須要定位的時候,本身手動點擊按鈕,再去定位當前位置。  通過2天研究和諮詢,找到了解決方案,在此備忘一下。

   注意:定位使用真機纔可以真正定位;模擬器的話,在DDMS中的Emulator Control中,選擇Manual,下面單選按鈕選擇Decimal,而後填寫經緯度,send後,再點擊定位個人位置按鈕,就能定位了(這應該算是固定定位,哈哈。。。)、 android

         一、第一步固然是獲取一個針對本身項目的key值。http://dev.baidu.com/wiki/static/imap/key/ git

二、使用百度API是有前提的,摘自百度:首先將API包括的兩個文件baidumapapi.jar和libBMapApiEngine.so拷貝到工程根目錄及libs\armeabi目錄下,並在工程屬性->Java Build Path->Libraries中選擇「Add JARs」,選定baidumapapi.jar,肯定後返回,這樣您就能夠在您的程序中使用API了。(這兩個文件見附件)。 api

三、按照本身的需求寫一個layout,個人以下: 緩存

     <?xml version="1.0" encoding="utf-8"?> 網絡

Xml代碼  收藏代碼
  1. <LinearLayout 
  2.   xmlns:android="http://schemas.android.com/apk/res/android" 
  3.   android:orientation="vertical" 
  4.   android:layout_width="fill_parent" 
  5.   android:layout_height="fill_parent" 
  6.   > 
  7.    
  8.   <TextView  
  9.     android:id="@+id/myLocation_id"  
  10.     android:layout_width="fill_parent"  
  11.     android:layout_height="wrap_content" 
  12.     android:textSize="15dp" 
  13.     android:gravity="center_horizontal" 
  14.     android:textColor="@drawable/black" 
  15.     android:background="@drawable/gary" 
  16.     /> 
  17.      
  18.   <com.baidu.mapapi.MapView android:id="@+id/bmapsView" 
  19.     android:layout_width="fill_parent" android:layout_height="fill_parent"  
  20.     android:clickable="true"  android:layout_weight="1"    
  21.    /> 
  22.    
  23.   <Button  
  24.       android:layout_width="wrap_content"  
  25.       android:layout_height="wrap_content"  
  26.       android:id="@+id/location_button_id"  
  27.       android:text="@string/location_button_text" 
  28.    /> 
  29.      
  30. </LinearLayout> 

須要特別注意的是:<com.baidu.mapapi.MapView  /> 這玩意。 app

四、寫一個MapApplication實現application,提供全局的BMapManager,以及其初始化。 異步

Java代碼  收藏代碼
  1. public BMapManager mapManager = null
  2. static MapApplication app; 
  3. public String mStrKey = "你申請的key值"
  4.  
  5. @Override 
  6. public void onCreate() { 
  7.     mapManager = new BMapManager(this); 
  8.     mapManager.init(mStrKey, new MyGeneralListener()); 
  9. @Override 
  10. //建議在您app的退出以前調用mapadpi的destroy()函數,避免重複初始化帶來的時間消耗 
  11. public void onTerminate() { 
  12.     // TODO Auto-generated method stub 
  13.     if(mapManager != null
  14.     { 
  15.         mapManager.destroy(); 
  16.         mapManager = null
  17.     } 
  18.     super.onTerminate(); 
  19.  
  20. static class MyGeneralListener implements MKGeneralListener{ 
  21.  
  22.     @Override 
  23.     public void onGetNetworkState(int arg0) { 
  24.         Toast.makeText(MapApplication.app.getApplicationContext(), "您的網絡出錯啦!"
  25.                 Toast.LENGTH_LONG).show(); 
  26.     } 
  27.     @Override 
  28.     public void onGetPermissionState(int iError) { 
  29.         if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) { 
  30.             // 受權Key錯誤: 
  31.             Toast.makeText(MapApplication.app.getApplicationContext(),"您的受權Key不正確!"
  32.                     Toast.LENGTH_LONG).show(); 
  33.         } 
  34.     } 
  35. 5、接下來就是按照百度api寫定位代碼了,使用handler機制去添加定位圖層,須要說明的都在註釋上了。 
  36.  
  37.        private BMapManager mBMapMan = null
  38. private MapView mMapView = null
  39. private MapController bMapController; 
  40. private MKLocationManager mkLocationManager; 
  41. private MKSearch mkSearch; 
  42.  
  43. private TextView address_view;   //定位到的位置信息 
  44.  
  45. private ProgressDialog dialog; 
  46. private List<HotelInfo> hotelList; 
  47.  
  48. private int distance = 1000//查詢的範圍(單位:m) 
  49.  
  50.    Handler handler = new Handler(){ 
  51.     @Override 
  52.     public void handleMessage(Message msg) { 
  53.          
  54.         double lat = msg.getData().getDouble("lat"); 
  55.         double lon = msg.getData().getDouble("lon"); 
  56.         if(lat!=0&&lon!=0){ 
  57.             GeoPoint point = new GeoPoint( 
  58.                     (int) (lat * 1E6), 
  59.                     (int) (lon * 1E6)); 
  60.             bMapController.animateTo(point);  //設置地圖中心點 
  61.             bMapController.setZoom(15); 
  62.              
  63.             mkSearch.reverseGeocode(point);   //解析地址(異步方法) 
  64.              
  65.             MyLocationOverlay myLoc = new MyLocationOverlayFromMap(ShowMapAct.this,mMapView); 
  66.             myLoc.enableMyLocation();   // 啓用定位 
  67.             myLoc.enableCompass();      // 啓用指南針 
  68.             mMapView.getOverlays().add(myLoc); 
  69.         }else
  70.             Toast.makeText(ShowMapAct.this, "沒有加載到您的位置", Toast.LENGTH_LONG).show(); 
  71.         } 
  72.          
  73.         if(hotelList!=null){ 
  74.             Drawable marker = getResources().getDrawable(R.drawable.iconmarka);  //設置marker 
  75.             marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight());   //爲maker定義位置和邊界 
  76.             mMapView.getOverlays().add(new OverItemList(marker,hotelList,ShowMapAct.this,bMapController)); 
  77.         }else if(hotelList==null&&lat!=0&&lon!=0){ 
  78.             Toast.makeText(ShowMapAct.this, "網絡異常,沒有獲取到酒店信息。", Toast.LENGTH_LONG).show(); 
  79.         } 
  80.         if(dialog!=null)  dialog.dismiss(); 
  81.     } 
  82.   }; 
  83.  
  84. @Override 
  85. protected void onCreate(Bundle savedInstanceState) { 
  86.      
  87.     distance = getIntent().getExtras().getInt("distance");   //獲取查詢範圍 
  88.      
  89.     super.onCreate(savedInstanceState); 
  90.     setContentView(R.layout.location); 
  91.      
  92.     mMapView = (MapView)findViewById(R.id.bmapsView);   //初始化一個mapView  存放Map 
  93.     init();  //初始化地圖管理器 
  94.     super.initMapActivity(mBMapMan); 
  95.      
  96.      
  97.     address_view = (TextView)findViewById(R.id.myLocation_id); 
  98.     SpannableStringBuilder style = new SpannableStringBuilder(String.format(getResources().getString(R.string.location_text),"位置不詳")); 
  99.     style.setSpan(new ForegroundColorSpan(Color.RED), 5, style.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
  100.     address_view.setText(style); 
  101.      
  102.     Button location_button = (Button)findViewById(R.id.location_button_id); 
  103.     location_button.setOnClickListener(new View.OnClickListener(){ 
  104.         @Override 
  105.         public void onClick(View v) { 
  106.              dialog = ProgressDialog.show(ShowMapAct.this, "", "數據加載中,請稍後....."); 
  107.              new Thread(new MyThread()).start(); 
  108.         } 
  109.     }); 
  110.      
  111.     mkSearch = new MKSearch();   //初始化一個MKSearch,根據location解析詳細地址 
  112.     mkSearch.init(mBMapMan, this); 
  113.        mMapView.setBuiltInZoomControls(true);   //啓用內置的縮放控件 
  114.        bMapController = mMapView.getController(); 
  115.        GeoPoint defaultPoint = new GeoPoint((int) (39.920934 * 1E6),(int) (116.412817 * 1E6));  //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6) 
  116.        bMapController.setCenter(defaultPoint);  //設置地圖中心點 
  117.        bMapController.setZoom(12);  //設置地圖zoom級別 
  118.         
  119.        mkLocationManager = mBMapMan.getLocationManager(); 
  120. /**
  121. * 初始化地圖管理器BMapManager
  122. */ 
  123. public void init(){ 
  124.     MapApplication app = (MapApplication)getApplication(); 
  125.        if (app.mapManager == null) { 
  126.         app.mapManager = new BMapManager(getApplication()); 
  127.         app.mapManager.init(app.mStrKey, new MapApplication.MyGeneralListener()); 
  128.        } 
  129.        mBMapMan = app.mapManager; 
  130.  
  131. @Override 
  132. protected void onDestroy() { 
  133.     MapApplication app = (MapApplication)getApplication(); 
  134.     if (mBMapMan != null) { 
  135.         mBMapMan.destroy(); 
  136.         app.mapManager.destroy(); 
  137.         app.mapManager = null
  138.         mBMapMan = null
  139.     } 
  140.     super.onDestroy(); 
  141.  
  142.   
  143.    @Override   
  144.    protected void onPause() {   
  145.        if (mBMapMan != null) {   
  146.            // 終止百度地圖API   
  147.         mBMapMan.stop();   
  148.        }   
  149.        super.onPause();   
  150.    } 
  151.   
  152.    @Override   
  153.    protected void onResume() { 
  154.        if (mBMapMan != null) {   
  155.            // 開啓百度地圖API   
  156.         mBMapMan.start();   
  157.        }   
  158.        super.onResume();   
  159.    } 
  160.  
  161. @Override 
  162. protected boolean isRouteDisplayed() { 
  163.     return false
  164.  
  165. @Override 
  166. public void onGetAddrResult(MKAddrInfo result, int iError) { 
  167.     if(result==null) return
  168.     SpannableStringBuilder style = new SpannableStringBuilder(String.format(getResources().getString(R.string.location_text),result.strAddr)); 
  169.     style.setSpan(new ForegroundColorSpan(Color.RED), 5, style.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
  170.     address_view.setText(style); 
  171.     if(dialog!=null) dialog.dismiss(); 
  172.  
  173. @Override 
  174. public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) {} 
  175. @Override 
  176. public void onGetPoiResult(MKPoiResult arg0, int arg1, int arg2) {} 
  177. @Override 
  178. public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {} 
  179. @Override 
  180. public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) {} 
  181.  
  182. /**
  183. * 從新定位,加載數據
  184. * @author Administrator
  185. *
  186. */ 
  187. class MyThread implements Runnable{ 
  188.     @Override 
  189.     public void run() { 
  190.         /**
  191.           * 最重要的就是這個玩意
  192.           * 因爲LocationListener獲取第一個位置修正的時間會很長,爲了不用戶等待,
  193.           * 在LocationListener獲取第一個更精確的位置以前,應當使用getLocationInfo() 獲取一個緩存的位置
  194.           */ 
  195.         Location location = mkLocationManager.getLocationInfo(); 
  196.         double lat = 0d,lon = 0d; 
  197.         if(location!=null){   //定位到位置 
  198.             String coordinate = location.getLatitude()+","+location.getLongitude(); 
  199.             HotelRemoteData hotelData = new HotelRemoteData(); 
  200.             /**
  201.              * 遠程獲取酒店列表數據
  202.              */ 
  203.             hotelList = hotelData.getHotelToMap(coordinate,distance); 
  204.             lat = location.getLatitude(); 
  205.             lon = location.getLongitude(); 
  206.         } 
  207.          
  208.         Message msg = new Message(); 
  209.         Bundle data = new Bundle(); 
  210.         data.putDouble("lat", lat); 
  211.         data.putDouble("lon", lon); 
  212.         msg.setData(data); 
  213.         handler.sendMessage(msg); 
  214.     } 

  六、還有一種就是百度示例至關推薦的,也是加載定位位置速度比較快的,那就是經過定位監聽器來定位信息。沒啥難的,照着百度的示例寫,都能搞定。 ide

Java代碼  收藏代碼
  1. LocationListener listener = new LocationListener() { 
  2.     @Override 
  3.     /** 位置變化,百度地圖即會調用該方法去獲取位置信息。
  4.       * (我測試發現就算手機不動,它也會偶爾從新去加載位置;只要你經過重力感應,他就必定會從新加載)
  5.       */ 
  6.     public void onLocationChanged(Location location) { 
  7.       GeoPoint gp =  new GeoPoint((int) (location.getLatitude() * 1E6), (int) (location.getLongitude() * 1E6));   //經過地圖上的經緯度轉換爲地圖上的座標點 
  8.       bMapController.animateTo(gp);  //動畫般的移動到定位的位置 
  9.     } 
  10. }; 
相關文章
相關標籤/搜索