android地图应用的开发,相信大家在网上都看过不少例子
不过基本上都是基于google地图的,有一点不好的是基于google地图开发的应用
不是每部手机都能够装的上去,要求设备系统本身支持google地图库才行
而如果采用高德公司的mapabc地图则摆脱了这种限制
下面本人就以基于mapabc的地图应用来阐述如何在地图上显示自身位置
为了让广大开发者方便将原有的google地图应用移植到mapabc上来
高德公司开发了与google map API相同的类与方法,基本上只要改变导入的包即可完成移植
稍后我会将mapabc的API相关文档同工程一并上传
废话不多说,先上几张效果图:
本例主要是获取自身经纬度,纠偏后在地图上显示图标
同时通过相应接口获取地理位置信息,点击位置图标弹出气泡显示地理位置信息
在获取自身经纬度有多种方式,android API里提供的LocationManager就可以通过GPS 或 网络 获取位置
不过使用该类的前提是设备上相关的设置选项要打开,否则是监听不到位置信息的
除此之外我们还可以获取基站信息然后通过google提供的基站定位接口来获取到经纬度
同时使用mapabc的话还可直接通过其提供的LocationManagerProxy类来监听获取位置
值得注意的是此时得到的位置已经是纠偏后的位置了
本例分别以以上三种定位方式获取位置然后在地图上显示
同时可通过菜单来比对基站定位与实际GPS定位的误差(在室外打开GPS选项来测试)
本人亲测google基站定位要比高德基站定位准一些,一般误差在一两百米以内
google到底是老大,不过纠偏的话当然还是高德准啦,自家的地图自家的算法
下面贴上部分源码稍作分析
且看主ACTIVITY有以下成员变量
public class TestMapABCDemoActivity extends MapActivity{
/** Called when the activity is first created. */
private final static String TAG = "TestMapABCDemoActivity";
private MapView mMapView; //地图VIEW
private MapController mMapController; //控制器
private List<Overlay> mOverlayList; //地图图层容器
private View mPopView; //地图气泡
private MyLocationManager mLocationManager; // LocationManager API获取位置
private MyLocationListen mListen;
private MyPositionOverlay mGoogleOverlay;
private MyStationLocationManager mStationLocationManager; //google基站接口获取位置
private MyStationLocationListen mStationLocationListen;
private MyPositionOverlay mStationOverlay;
private MyGaodeLocationManager mGaodeLocationManager; //高德基站接口获取位置
private MyGaodeListen mGaodeLocationListen;
private MyPositionOverlay mGaoDeOverlay;
private Handler mHandler;
初始化调以下两个方法
public void initView()
{
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,new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,
MapView.LayoutParams.WRAP_CONTENT,
null,
MapView.LayoutParams.BOTTOM_CENTER));
mPopView.setVisibility(View.GONE);
// android API定位自身位置图标
mGoogleOverlay = new MyPositionOverlay(this, getResources().getDrawable(R.drawable.marker_google), mPopView, mMapView);
mGoogleOverlay.setColor(Color.argb(50, 0, 119, 192));
mOverlayList.add(mGoogleOverlay);
// google基站定位自身位置图标
mStationOverlay = new MyPositionOverlay(this, getResources().getDrawable(R.drawable.marker_station) , mPopView, mMapView);
mStationOverlay.setColor(Color.argb(50, 255, 100, 55));
mOverlayList.add(mStationOverlay);
// 高德基站定位自身位置图标
mGaoDeOverlay = new MyPositionOverlay(this, getResources().getDrawable(R.drawable.marker_gaode), mPopView, mMapView);
mGaoDeOverlay.setColor(Color.argb(50, 0, 136, 25));
mOverlayList.add(mGaoDeOverlay);
GeoPoint point = new GeoPoint((int) (MyConstant.DOUBLE_STUDEN_LAT * 1E6),
(int) (MyConstant.DOUBLE_STUDEN_LON * 1E6)); //用给定的经纬度构造一个GeoPoint,
mMapController.setCenter(point); //设置地图中心点
mMapController.setZoom(15); //设置地图zoom级别
}
public void initLogic()
{
mHandler = new Handler()
{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
}
};
mLocationManager = new MyLocationManager(this);
mListen = new MyLocationListen(this, mHandler, new UpdateLocationRunnable());
mStationLocationManager = new MyStationLocationManager(this);
mStationLocationListen = new MyStationLocationListen(this, mHandler, new UpdateStationLocationRunnable());
mGaodeLocationManager = new MyGaodeLocationManager(this);
mGaodeLocationListen = new MyGaodeListen(mHandler, new UpdateGaodeLocationRunnable());
}
一个是地图相关控件的初始化,一个是三种定位方式的类对象初始化
在resume和pause里进行注册监听和反注册监听
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
// 取消监听
mLocationManager.unRegisterListen();
mStationLocationManager.unRegisterListen();
mGaodeLocationManager.unRegisterListen();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// 注册监听
mLocationManager.registerListen(mListen);
mStationLocationManager.registerListen(mStationLocationListen);
mGaodeLocationManager.registerListen(mGaodeLocationListen);
}
设置以三十秒的频率更新位置
在刷新位置后进行纠偏(LocationManagerProxy不用纠偏)和获取地理位置信息
由于这两个都要联网获取,所以不能在UI线程里操作
下面看看这三种定位方式的监听器实现
android API location监听器
public class MyLocationListen implements LocationListener
{
private Handler mHandler;
private IONSetLocation mRunnable;
private Context mContext;
public MyLocationListen(Context context, Handler handler, IONSetLocation runnable)
{
mHandler = handler;
mRunnable = runnable;
mContext = context;
}
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
if (mHandler != null)
{
Thread thread = new InnerThread(location);
thread.start();
}
}
class InnerThread extends Thread
{
private Location mLocation;
public InnerThread( Location location)
{
mLocation = location;
}
@Override
public void run() {
// TODO Auto-generated method stub
Location newLocation = WebManager.correctPosToMap(mLocation, mContext);
mRunnable.setLocation(newLocation);
try {
mRunnable.setAdress(WebManager.getAddressByGoogle(mLocation));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mHandler.post( mRunnable);
}
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
onLocationChange方法是在UI线程里执行的,所以需要开子线程进行查询操作
google基站 位置监听
public class MyStationLocationListen implements LocationListener
{
private Handler mHandler;
private IONSetLocation mRunnable;
private Context mContext;
public MyStationLocationListen(Context context, Handler handler, IONSetLocation runnable)
{
mHandler = handler;
mRunnable = runnable;
mContext = context;
}
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
if (mHandler != null)
{
Location newLocation = WebManager.correctPosToMap(location, mContext);
mRunnable.setLocation(newLocation);
try {
mRunnable.setAdress(WebManager.getAddressByGoogle(location));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mHandler.post( mRunnable);
}
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
这个所谓的位置监听是假的,其实就是开了个定时器每隔三十秒获取基站信息然后在获取位置
看它对应的locationmanager实现
public class MyStationLocationManager {
private final static int CHECK_POSITION_INTERVAL = 30 * 1000;
private Context mContext;
private Timer mTimer;
private MyTimeTask mTimeTask;
private LocationListener mListener;
public MyStationLocationManager(Context context)
{
mContext = context;
mTimer = new Timer();
}
public void registerListen(LocationListener listener)
{
if (mListener == null)
{
mListener = listener;
startTimer();
}
}
public void unRegisterListen()
{
stopTimer();
mListener = null;
}
private void startTimer( )
{
if (mTimeTask == null)
{
mTimeTask = new MyTimeTask();
mTimer.schedule(mTimeTask, 0, CHECK_POSITION_INTERVAL);
}
}
private void stopTimer()
{
if (mTimeTask != null)
{
mTimeTask.cancel();
mTimeTask = null;
}
}
class MyTimeTask extends TimerTask
{
@Override
public void run() {
// TODO Auto-generated method stub
//Toast.makeText(mContext, "run", Toast.LENGTH_SHORT).show();
List<CellIDInfo> list = null;
Location location = null;
try {
list = CellIDInfoManager.getCellIDInfo(mContext);
location = WebManager.callGear(list);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (mListener != null)
{
mListener.onLocationChanged(location);
}
}
}
}
看到木有
再看高德的
public class MyGaodeListen implements LocationListener
{
private Handler mHandler;
private IONSetLocation mRunnable;
public MyGaodeListen(Handler handler, IONSetLocation runnable)
{
mHandler = handler;
mRunnable = runnable;
}
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
if (mHandler != null)
{
mRunnable.setLocation(location);
try {
mRunnable.setAdress(WebManager.getAddressByGoogle(location));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mHandler.post( mRunnable);
}
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
public class MyGaodeLocationManager {
private final static int CHECK_POSITION_INTERVAL = 30 * 1000;
private LocationManagerProxy mLocationManagerProxy;
private Context mContext;
private LocationListener mListener;
public MyGaodeLocationManager(Context context)
{
mContext = context;
mLocationManagerProxy = LocationManagerProxy.getInstance(context, context.getString(R.string.maps_api_key));
}
public void clear()
{
mLocationManagerProxy.destory();
}
public void registerListen(LocationListener listener)
{
if (mListener == null)
{
mListener = listener;
mLocationManagerProxy.requestLocationUpdates(LocationProviderProxy.MapABCNetwork, CHECK_POSITION_INTERVAL, 0, listener);
}
}
public void unRegisterListen()
{
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