Android Map Api 使用和开发(2) 定位我的位置、地图弹出泡泡、通过经纬度获取地址
代码我传到csdn资源库了;http://download.csdn.net/detail/totogo2010/4335701
上篇把界面画出来了, 接下来就是显示里面的功能了,那这篇内容就比较丰富了。
主要有这么几道菜:
1、在地图上弹出泡泡显示信息,并且能相应泡泡的点击时间
2、自动定位当前位置(也就是我的位置) --添加了 GPS定位和基站定位。
3、获取经纬度对应的接到地址名称
那下面就开始代码把,理论知识能讲多少是多少。
一 、 地图弹出泡泡的制作
1 、overlay_popup.xml 直接把layout放出来
还有泡泡的效果图 ,很多同学做项目都是时间很紧张的,别人贴出来代码都觉得不够直观,有截图是王道,
顺应大部分懒人的习惯,我编截图边发:
看到了吧, 泡泡上有title ,有 desc ,还有一个小icon。我把整个layout 设置成:
android:clickable="true" android:focusable="true"
这样这个layout就相当余一个button了,可以点击。
2、那代码怎么实现呢? FzMapActivity里加入下面代码
在进入主界面是 初始化一下view。
private View popView;当然这个变量定义也不能少。
3、自定义 itemizedOverlay MyItemizedOverlay
好把,先把代码放出来,光描述怎么写太费劲了。
主要是继承 OnFocusChangeListener 监听地图层的变化, 为了方便监听button事件也继承了OnClickListener。
下面这方法监听这个层改变的时间,把泡泡弹出来。
public void onFocusChanged(ItemizedOverlay overlay, OverlayItem newFocus) {
Log.d(TAG , "item focus changed!");
if (null != newFocus) {
Log.d(TAG , "centerY : " + itemDrawable.getBounds().centerY() + "; centerX :" + itemDrawable.getBounds().centerX());
Log.d(TAG , " height : " + itemDrawable.getBounds().height());
MapView.LayoutParams params = (MapView.LayoutParams) mPopView.getLayoutParams();
params.x = this.layout_x;//Y轴偏移
params.y = this.layout_y;//Y轴偏移
point = newFocus.getPoint();
params.point = point;
mMapCtrl.animateTo(point);
TextView title_TextView = (TextView) mPopView.findViewById(R.id.map_bubbleTitle);
title_TextView.setText(newFocus.getTitle());
TextView desc_TextView = (TextView) mPopView.findViewById(R.id.map_bubbleText);
if(null == newFocus.getSnippet() || "".equals(newFocus.getSnippet())){
desc_TextView.setVisibility(View.GONE);
}else{
desc = newFocus.getSnippet();
desc_TextView.setText(desc);
desc_TextView.setVisibility(View.VISIBLE);
}
RelativeLayout button = (RelativeLayout) mPopView.findViewById(R.id.map_bubblebtn);
button.setOnClickListener(this);
mMapView.updateViewLayout(mPopView, params);
mPopView.setVisibility(View.VISIBLE);
selectItem = newFocus;
}
}
二、长按地图获取地图位置并弹出泡泡显示信息
它的继承关系 LongPressOverlay extends Overlay implements OnDoubleTapListener
LongPressOverlay这个层主要是用来接收长按事件 和双击地图界面的
@Override
public void onLongPress(MotionEvent e) {
mContext.locPoint = mMapView.getProjection().fromPixels((int) e.getX(),
(int) e.getY());
mHandler.sendEmptyMessage(mContext.MSG_VIEW_LONGPRESS);
}接收到长按事件后给主界面发消息,由主界面处理。
三、FzLocationManager 这个类用来做gps,基站定位
public interface LocationCallBack{
/**
* 当前位置
* @param location
*/
void onCurrentLocation(Location location);
}
定义一个接口 ,当监听到位置变化时,回调主界面
//locationListener注册监听器到位置服务管理里
networkLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, MINTIME, MININSTANCE,
locationListener);
//位置信息变化回调
private void updateLocation(Location location) {
lastLocation = location;
mCallback.onCurrentLocation(location);
}
四、主界面逻辑
主界面有
部分注释写在代码里了
最后再上一张截图,在室内通过基站定位到我的位置:
五、通过经纬度获取地址
这个单独拷贝出来让大家看看。这个方法获取地址有时候获取不到的,google好像对这个接口有限制。说白了就这这个接口不靠谱。
大家可以尝试用别的方法或手段获取地址
我的代码里加了个死循环去获取位置,这样的方案是不可取的,不过暂时用一下看看效果也好。
/**
* 通过经纬度获取地址
* @param point
* @return
*/
private String getLocationAddress(GeoPoint point){
String add = "";
Geocoder geoCoder = new Geocoder(getBaseContext(),
Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(
point.getLatitudeE6() / 1E6, point.getLongitudeE6() / 1E6, 1);
Address address = addresses.get(0);
int maxLine = address.getMaxAddressLineIndex();
if(maxLine >= 2){
add = address.getAddressLine(1) + address.getAddressLine(2);
}else {
add = address.getAddressLine(1);
}
} catch (IOException e) {
add = "";
e.printStackTrace();
}
return add;
}
好了,以上是所有代码, AndroidManifest.xml 在 (一)里有。
最后小结
用google的api获取到的位置放到他的地图上是有偏差的,而且偏差还比不小,大家可以观察一下,这个问题没有很好的免费解决方案。
如果有哪位有什么好建议可以发出来,谢谢。
用基站和gps定位是,也没有处理那个是更好的定位的问题。
欢迎大家提建议