編輯:關於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()方法,即可以動畫的形式移動到新的定位點去,實現實時自動地圖定位的功能。
首先我們來了解一下SAX解析器的基本知識: SAX(Simple API for XML)解析器是一種基於事件的解析器,事件驅動的流式解析方式是,從文件的開始順序解析到文
View布局告一段落,從本篇開始View事件相關分析,今天分析的是View的事件分發機制(PS:本篇文章中源碼均是android 6.0,請知曉)View 事件的分發機制
安裝Android Studio相關教程(不翻牆版)這篇文章是當年自己剛用android studio時寫的,主要是當時同班同學問題太多,後來我直接寫了這篇。現在發上來給
Android CardView詳解Android5.0中向我們介紹了一個全新的控件–CardView,從本質上看,可以將CardView看做是FrameLa