android地图应用的开发,相信大家在网上都看过不少例子
不过基本上都是基于google地图的,有一点不好的是基于google地图开发的应用
不是每部手机都能够装的上去,要求设备系统本身支持google地图库才行
而如果采用高德公司的mapabc地图则摆脱了这种限制
下面本人就以基于mapabc的地图应用来阐述如何在地图上显示自身位置
为了让广大开发者方便将原有的google地图应用移植到mapabc上来
高德公司开发了与googlemapAPI相同的类与方法,基本上只要改变导入的包即可完成移植
稍后我会将mapabc的API相关文档同工程一并上传
废话不多说,先上几张效果图:
本例主要是获取自身经纬度,纠偏后在地图上显示图标
同时通过相应接口获取地理位置信息,点击位置图标弹出气泡显示地理位置信息
在获取自身经纬度有多种方式,androidAPI里提供的LocationManager就可以通过GPS或网络获取位置
不过使用该类的前提是设备上相关的设置选项要打开,否则是监听不到位置信息的
除此之外我们还可以获取基站信息然后通过google提供的基站定位接口来获取到经纬度
同时使用mapabc的话还可直接通过其提供的LocationManagerProxy类来监听获取位置
值得注意的是此时得到的位置已经是纠偏后的位置了
本例分别以以上三种定位方式获取位置然后在地图上显示
同时可通过菜单来比对基站定位与实际GPS定位的误差(在室外打开GPS选项来测试)
本人亲测google基站定位要比高德基站定位准一些,一般误差在一两百米以内
google到底是老大,不过纠偏的话当然还是高德准啦,自家的地图自家的算法
下面贴上部分源码稍作分析
且看主ACTIVITY有以下成员变量
publicclassTestMapABCDemoActivityextendsMapActivity{
/**Calledwhentheactivityisfirstcreated.*/
privatefinalstaticStringTAG="TestMapABCDemoActivity";
privateMapViewmMapView;//地图VIEW
privateMapControllermMapController;//控制器
privateList<Overlay>mOverlayList;//地图图层容器
privateViewmPopView;//地图气泡
privateMyLocationManagermLocationManager;//LocationManagerAPI获取位置
privateMyLocationListenmListen;
privateMyPositionOverlaymGoogleOverlay;
privateMyStationLocationManagermStationLocationManager;//google基站接口获取位置
privateMyStationLocationListenmStationLocationListen;
privateMyPositionOverlaymStationOverlay;
privateMyGaodeLocationManagermGaodeLocationManager;//高德基站接口获取位置
privateMyGaodeListenmGaodeLocationListen;
privateMyPositionOverlaymGaoDeOverlay;
privateHandlermHandler;
初始化调以下两个方法
publicvoidinitView()
{
mMapView=(MapView)findViewById(R.id.main_mapView);
mMapView.setBuiltInZoomControls(true);//设置启用内置的缩放控件
mMapController=mMapView.getController();//得到mMapView的控制权,可以用它控制和驱动平移和缩放
mOverlayList=mMapView.getOverlays();//得到图层容器
//设置气泡位置
mPopView=getLayoutInflater().inflate(R.layout.map_popup,null);
mMapView.addView(mPopView,newMapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,
MapView.LayoutParams.WRAP_CONTENT,
null,
MapView.LayoutParams.BOTTOM_CENTER));
mPopView.setVisibility(View.GONE);
//androidAPI定位自身位置图标
mGoogleOverlay=newMyPositionOverlay(this,getResources().getDrawable(R.drawable.marker_google),mPopView,mMapView);
mGoogleOverlay.setColor(Color.argb(50,0,119,192));
mOverlayList.add(mGoogleOverlay);
//google基站定位自身位置图标
mStationOverlay=newMyPositionOverlay(this,getResources().getDrawable(R.drawable.marker_station),mPopView,mMapView);
mStationOverlay.setColor(Color.argb(50,255,100,55));
mOverlayList.add(mStationOverlay);
//高德基站定位自身位置图标
mGaoDeOverlay=newMyPositionOverlay(this,getResources().getDrawable(R.drawable.marker_gaode),mPopView,mMapView);
mGaoDeOverlay.setColor(Color.argb(50,0,136,25));
mOverlayList.add(mGaoDeOverlay);
GeoPointpoint=newGeoPoint((int)(MyConstant.DOUBLE_STUDEN_LAT*1E6),
(int)(MyConstant.DOUBLE_STUDEN_LON*1E6));//用给定的经纬度构造一个GeoPoint,
mMapController.setCenter(point);//设置地图中心点
mMapController.setZoom(15);//设置地图zoom级别
}
publicvoidinitLogic()
{
mHandler=newHandler()
{
@Override
publicvoidhandleMessage(Messagemsg){
//TODOAuto-generatedmethodstub
}
};
mLocationManager=newMyLocationManager(this);
mListen=newMyLocationListen(this,mHandler,newUpdateLocationRunnable());
mStationLocationManager=newMyStationLocationManager(this);
mStationLocationListen=newMyStationLocationListen(this,mHandler,newUpdateStationLocationRunnable());
mGaodeLocationManager=newMyGaodeLocationManager(this);
mGaodeLocationListen=newMyGaodeListen(mHandler,newUpdateGaodeLocationRunnable());
}
一个是地图相关控件的初始化,一个是三种定位方式的类对象初始化
在resume和pause里进行注册监听和反注册监听
@Override
protectedvoidonPause(){
//TODOAuto-generatedmethodstub
super.onPause();
//取消监听
mLocationManager.unRegisterListen();
mStationLocationManager.unRegisterListen();
mGaodeLocationManager.unRegisterListen();
}
@Override
protectedvoidonResume(){
//TODOAuto-generatedmethodstub
super.onResume();
//注册监听
mLocationManager.registerListen(mListen);
mStationLocationManager.registerListen(mStationLocationListen);
mGaodeLocationManager.registerListen(mGaodeLocationListen);
}
设置以三十秒的频率更新位置
在刷新位置后进行纠偏(LocationManagerProxy不用纠偏)和获取地理位置信息
由于这两个都要联网获取,所以不能在UI线程里操作
下面看看这三种定位方式的监听器实现
androidAPIlocation监听器
publicclassMyLocationListenimplementsLocationListener
{
privateHandlermHandler;
privateIONSetLocationmRunnable;
privateContextmContext;
publicMyLocationListen(Contextcontext,Handlerhandler,IONSetLocationrunnable)
{
mHandler=handler;
mRunnable=runnable;
mContext=context;
}
@Override
publicvoidonLocationChanged(Locationlocation){
//TODOAuto-generatedmethodstub
if(mHandler!=null)
{
Threadthread=newInnerThread(location);
thread.start();
}
}
classInnerThreadextendsThread
{
privateLocationmLocation;
publicInnerThread(Locationlocation)
{
mLocation=location;
}
@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
LocationnewLocation=WebManager.correctPosToMap(mLocation,mContext);
mRunnable.setLocation(newLocation);
try{
mRunnable.setAdress(WebManager.getAddressByGoogle(mLocation));
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
mHandler.post(mRunnable);
}
}
@Override
publicvoidonProviderDisabled(Stringprovider){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidonProviderEnabled(Stringprovider){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidonStatusChanged(Stringprovider,intstatus,Bundleextras){
//TODOAuto-generatedmethodstub
}
}
onLocationChange方法是在UI线程里执行的,所以需要开子线程进行查询操作
google基站位置监听
publicclassMyStationLocationListenimplementsLocationListener
{
privateHandlermHandler;
privateIONSetLocationmRunnable;
privateContextmContext;
publicMyStationLocationListen(Contextcontext,Handlerhandler,IONSetLocationrunnable)
{
mHandler=handler;
mRunnable=runnable;
mContext=context;
}
@Override
publicvoidonLocationChanged(Locationlocation){
//TODOAuto-generatedmethodstub
if(mHandler!=null)
{
LocationnewLocation=WebManager.correctPosToMap(location,mContext);
mRunnable.setLocation(newLocation);
try{
mRunnable.setAdress(WebManager.getAddressByGoogle(location));
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
mHandler.post(mRunnable);
}
}
@Override
publicvoidonProviderDisabled(Stringprovider){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidonProviderEnabled(Stringprovider){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidonStatusChanged(Stringprovider,intstatus,Bundleextras){
//TODOAuto-generatedmethodstub
}
}
这个所谓的位置监听是假的,其实就是开了个定时器每隔三十秒获取基站信息然后在获取位置
看它对应的locationmanager实现
publicclassMyStationLocationManager{
privatefinalstaticintCHECK_POSITION_INTERVAL=30*1000;
privateContextmContext;
privateTimermTimer;
privateMyTimeTaskmTimeTask;
privateLocationListenermListener;
publicMyStationLocationManager(Contextcontext)
{
mContext=context;
mTimer=newTimer();
}
publicvoidregisterListen(LocationListenerlistener)
{
if(mListener==null)
{
mListener=listener;
startTimer();
}
}
publicvoidunRegisterListen()
{
stopTimer();
mListener=null;
}
privatevoidstartTimer()
{
if(mTimeTask==null)
{
mTimeTask=newMyTimeTask();
mTimer.schedule(mTimeTask,0,CHECK_POSITION_INTERVAL);
}
}
privatevoidstopTimer()
{
if(mTimeTask!=null)
{
mTimeTask.cancel();
mTimeTask=null;
}
}
classMyTimeTaskextendsTimerTask
{
@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
//Toast.makeText(mContext,"run",Toast.LENGTH_SHORT).show();
List<CellIDInfo>list=null;
Locationlocation=null;
try{
list=CellIDInfoManager.getCellIDInfo(mContext);
location=WebManager.callGear(list);
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
if(mListener!=null)
{
mListener.onLocationChanged(location);
}
}
}
}
看到木有
再看高德的
publicclassMyGaodeListenimplementsLocationListener
{
privateHandlermHandler;
privateIONSetLocationmRunnable;
publicMyGaodeListen(Handlerhandler,IONSetLocationrunnable)
{
mHandler=handler;
mRunnable=runnable;
}
@Override
publicvoidonLocationChanged(Locationlocation){
//TODOAuto-generatedmethodstub
if(mHandler!=null)
{
mRunnable.setLocation(location);
try{
mRunnable.setAdress(WebManager.getAddressByGoogle(location));
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
mHandler.post(mRunnable);
}
}
@Override
publicvoidonProviderDisabled(Stringprovider){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidonProviderEnabled(Stringprovider){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidonStatusChanged(Stringprovider,intstatus,Bundleextras){
//TODOAuto-generatedmethodstub
}
}
publicclassMyGaodeLocationManager{
privatefinalstaticintCHECK_POSITION_INTERVAL=30*1000;
privateLocationManagerProxymLocationManagerProxy;
privateContextmContext;
privateLocationListenermListener;
publicMyGaodeLocationManager(Contextcontext)
{
mContext=context;
mLocationManagerProxy=LocationManagerProxy.getInstance(context,context.getString(R.string.maps_api_key));
}
publicvoidclear()
{
mLocationManagerProxy.destory();
}
publicvoidregisterListen(LocationListenerlistener)
{
if(mListener==null)
{
mListener=listener;
mLocationManagerProxy.requestLocationUpdates(LocationProviderProxy.MapABCNetwork,CHECK_POSITION_INTERVAL,0,listener);
}
}
publicvoidunRegisterListen()
{
if(mListener!=null)
{
mLocationManagerProxy.removeUpdates(mListener);
}
}
}
采用自家的LocationManagerProxy调用requestLocationUpdates(LocationProviderProxy.MapABCNetwork,CHECK_POSITION_INTERVAL,0,listener);
器MapABCNetwork的值是lbs,得到的位置无需纠偏即可显示
地图气泡的知识在此就不多做解释了,网上搜搜吧
代码分析到此为止,附属工程链接:
http://download.csdn.net/detail/geniuseoe2012/4345880
还有mapabc官方文档(很齐全哦)
http://download.csdn.net/detail/geniuseoe2012/4345909