Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 高德地圖 android api 實現自動定位

高德地圖 android api 實現自動定位

編輯:關於Android編程

浣熊我最近在研究高德地圖android api,看到第三章定位信息後半部分關於“如何通過MyLocationOverlay 實現自動定位”的時候我凌亂了,寫得過於簡單,根本不知道如何操作。最後通過閱讀官方的示例代碼和在網上搜集大量資料實現了地圖自動定位的功能。

開發指南第三章定位信息前半部分的代碼實現的功能是:當手機采集的地理位置(經緯度)發生改變時在界面上顯示出改變後的經緯度。如果開發過android原生定位程序的開發者應該對這部分代碼不陌生,中規中矩,先注冊位置監聽服務,然後當位置發生改變後出發onLocationChanged()方法。現在請在官網上下載示例代碼,導入工程後開啟包com.amap.cn.apis.location中的MyLocation.java文件,該文件實現的主要功能是:初始化地圖並且實現首次定位,地圖會自動移動到定位點,我們一會便要基於這個文件來完成地圖自動實時定位的功能。

看到這兒,有人可能想把MyLocation文件中的內容與第三章給出的android原生定位模塊簡單整合。如果你的解決思路是:在onLocationChanged()方法中企圖在地圖上繪制出當前的位置,那麼就會遇到很大的麻煩。因為如果用高德地圖提供的api在地圖上繪制定位點的話一定要調用類MyLocationOverlay中的enableMyLocation()方法,根據官方參考資料,這個方法封裝了android原生的類LocationManager中的requestLocationUpdates()方法,所以你在寫onLocationChanged()方法前一定是已經調用了原生的類LocationManager中的requestLocationUpdates()方法,這樣一來造成了LocationManager在沒有removeUpdate前又進行了一次requestLocationUpdates,由此造成程序意外退出。

所以還是回到開發指南第三章,好好看看後半部分:如果想讓地圖跟隨當前位置移動,需要繼承MyLocationOverlay 並實現其onLocationChanged()方法,調用MapView.getController().animateTo()方法移動地圖位置。官方用戶指南上的這句原話正是問題的正解,不過官網實在太坑爹,簡簡單單幾行文字和代碼,對於浣熊這種剛剛接觸地圖開發的小白來說實在是看得一頭霧水,還在一陣瞎折騰,終於解決了問題,所以共享出來,希望和我一樣的小白能夠少走些彎路。

我先把修改後的MyLocation.java文件整個貼出來,在增加或改動的代碼前後均表明了注釋(不包括包的改動):“/*change start*/”和"/*change end*/"


[java]
?/**
 * 使用MyLocationOverlay實現地圖自動定位
 * 實現初次定位使定位結果居中顯示
 */ 
public class MyLocation extends MapActivity { 
    private MapView mMapView; 
    private MapController mMapController; 
    private GeoPoint point; 
     
    /*change start*/ 
    private MyLocationOverlay_HX mLocationOverlay; 
    /*change end*/ 
     
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.mapview); 
        mMapView = (MapView) findViewById(R.id.mapView); 
        mMapView.setBuiltInZoomControls(true);   
        mMapController = mMapView.getController();   
        point = new GeoPoint((int) (39.90923 * 1E6), 
                (int) (116.397428 * 1E6));  //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6)  
        mMapController.setCenter(point);  //設置地圖中心點  
        mMapController.setZoom(15); 
         
        /*change start*/ 
        mLocationOverlay = new MyLocationOverlay_HX(this, mMapView); 
        /*change end*/ 
         
        mMapView.getOverlays().add(mLocationOverlay); 
        //實現初次定位使定位結果居中顯示  
        mLocationOverlay.runOnFirstFix(new Runnable() { 
            public void run() { 
                handler.sendMessage(Message.obtain(handler, Constants.FIRST_LOCATION)); 
            } 
        }); 
    } 
     
    /*change start*/ 
    class MyLocationOverlay_HX extends MyLocationOverlay { 
 
        public MyLocationOverlay_HX(Context arg0, MapView arg1) { 
            super(arg0, arg1); 
            // TODO Auto-generated constructor stub  
        } 
         
        public void onLocationChanged(Location location) { 
            //Toast.makeText(getApplicationContext(), "Location Changed",Toast.LENGTH_LONG).show();   
             
            point = new GeoPoint((int) (location.getLatitude() * 1E6), 
                    (int) (location.getLongitude() * 1E6));  //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6)  
            //mMapController.setCenter(point);  //設置地圖中心點  
            mMapController.animateTo(point); 
            super.onLocationChanged(location); 
        } 
         
    } 
    /*change end*/ 
     
    @Override 
    protected void onPause() { 
        this.mLocationOverlay.disableMyLocation(); 
        super.onPause(); 
    } 
 
    @Override 
    protected void onResume() { 
        this.mLocationOverlay.enableMyLocation(); 
        super.onResume(); 
    } 
 
    private Handler handler = new Handler() { 
        public void handleMessage(Message msg) { 
            if (msg.what == Constants.FIRST_LOCATION) { 
                mMapController.animateTo(mLocationOverlay.getMyLocation()); 
            } 
        } 
    }; 

/**
 * 使用MyLocationOverlay實現地圖自動定位
 * 實現初次定位使定位結果居中顯示
 */
public class MyLocation extends MapActivity {
 private MapView mMapView;
 private MapController mMapController;
 private GeoPoint point;
 
 /*change start*/
 private MyLocationOverlay_HX mLocationOverlay;
 /*change end*/
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mapview);
  mMapView = (MapView) findViewById(R.id.mapView);
  mMapView.setBuiltInZoomControls(true); 
  mMapController = mMapView.getController(); 
  point = new GeoPoint((int) (39.90923 * 1E6),
    (int) (116.397428 * 1E6));  //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6)
  mMapController.setCenter(point);  //設置地圖中心點
  mMapController.setZoom(15);
  
  /*change start*/
  mLocationOverlay = new MyLocationOverlay_HX(this, mMapView);
  /*change end*/
  
  mMapView.getOverlays().add(mLocationOverlay);
  //實現初次定位使定位結果居中顯示
  mLocationOverlay.runOnFirstFix(new Runnable() {
            public void run() {
             handler.sendMessage(Message.obtain(handler, Constants.FIRST_LOCATION));
            }
        });
    }
   
    /*change start*/
    class MyLocationOverlay_HX extends MyLocationOverlay {

  public MyLocationOverlay_HX(Context arg0, MapView arg1) {
   super(arg0, arg1);
   // TODO Auto-generated constructor stub
  }
  
  public void onLocationChanged(Location location) {
   //Toast.makeText(getApplicationContext(), "Location Changed",Toast.LENGTH_LONG).show();
   
   point = new GeoPoint((int) (location.getLatitude() * 1E6),
     (int) (location.getLongitude() * 1E6));  //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6)
   //mMapController.setCenter(point);  //設置地圖中心點
   mMapController.animateTo(point);
   super.onLocationChanged(location);
  }
     
    }
    /*change end*/
   
    @Override
 protected void onPause() {
     this.mLocationOverlay.disableMyLocation();
  super.onPause();
 }

 @Override
 protected void onResume() {
  this.mLocationOverlay.enableMyLocation();
  super.onResume();
 }

 private Handler handler = new Handler() {
  public void handleMessage(Message msg) {
   if (msg.what == Constants.FIRST_LOCATION) {
    mMapController.animateTo(mLocationOverlay.getMyLocation());
   }
  }
    };
}
最關鍵就在於我在程序中繼承了類MyLocationOverlay,將繼承類命名為MyLocationOverlay_HX,並在其中重寫了onLocationChanged()方法,從代碼中可以看出,當位置改變時會觸發類MyLocationOverlay的onLocationChanged()方法,然後可以獲取位置的經緯度坐標信息,由該信息構建point數據結構,並將其傳給類MapController的animateTo()方法,即可以動畫的形式移動到新的定位點去,實現實時自動地圖定位的功能。

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