接上篇 http://www.cnblogs.com/inkheart0124/p/3536322.html

1,在地图上打个标记

 private MarkerOptions mMarkOption;

 mMarkOption = new MarkerOptions().icon(BitmapDescriptorFactory.fromAsset("target.png"));
mMarkOption.draggable(true); double dLat = mLocation.getLatitude();
double dLong = mLocation.getLongitude(); LatLng latlng = new LatLng(dLat, dLong); mMarkOption.position(latlng);
mMarkOption.title("title");
mMarkOption.snippet("snippet");
Marker mMarker = mMapView.addMarker(mMarkOption);

3行,MarkerOptions对象,自己设置一个icon( target.png

4行,设置为可拖动

6~9行,构造当前经纬度的LatLng

11~13行,设置标记的位置,info window的标题title、详细snippet

14行,GoogleMap的 addMarker(MarkerOptions) 方法,把标记添加到地图上,返回Marker对象mMarker。

2,拖动标记

设置标记可拖动:

方法一、先设置mMarkOption.draggable(true);,再addMarker;

方法二、Marker的setDraggable(boolean)方法;

Google Map 默认长按标记开始拖动,开发者只需要注册监听。注册拖动事件监听

mMapView.setOnMarkerDragListener(this);

acitiviy实现OnMarkerDragListener接口如下:

 /* OnMarkerDragListener start */
@Override
public void onMarkerDrag(Marker marker) {
} @Override
public void onMarkerDragEnd(Marker marker) {
} @Override
public void onMarkerDragStart(Marker marker) {
if(marker.isInfoWindowShown())
marker.hideInfoWindow();
mMarkerLoaded = false;
}
/* OnMarkerDragListener end */

3行,public void onMarkerDrag(Marker marker),当Marker拖动的过程中会不断调用此函数,拖动中marker的位置marker.getPosition()可以得到经纬度。

7行,public void onMarkerDragEnd(Marker marker),拖动结束

11行,public void onMarkerDragStart(Marker marker),开始拖动

11~15行,开始拖动的时候,判断如果正在显示info window,则隐藏info window。

3,点击标记弹出info window

点击marker的default动作就是显示info window,之前设置的title和snippet会显示在infowindow中。

我们对info window做一点小改造,让他显示一个小图标和标记地点的地址

代码:

activity 实现InfoWindowAdapter接口(implements InfoWindowAdapter)

调用GoogleMap的方法setInfoWindowAdapter()方法

mMapView.setInfoWindowAdapter(this);

activity中实现InfoWindowAdapter的两个方法:

public View getInfoWindow(Marker marker);返回的View将用于构造整个info window的窗口

public View getInfoContents(Marker marker);返回的View将用于构造info window的显示内容,保留原来的窗口背景和框架

首先需要定义一个View的布局

res/layout/map_info.xml

 <?xml version="1.0" encoding="utf-8"?>

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
> <ImageView
android:id="@+id/map_info_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="0dip"
android:layout_marginTop="0dip"
/> <LinearLayout
android:layout_toRightOf="@id/map_info_image"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="0dip"
android:orientation="vertical"
>
<TextView
android:id="@+id/map_info_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="map_info_title"
android:layout_gravity="center"
/> <TextView
android:id="@+id/map_info_snippet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="map_info_snippet"
android:layout_gravity="center"
/> </LinearLayout> </RelativeLayout>

实现getInfoContents函数:

 /* GoogleMap.InfoWindowAdapter begin */
private View mInfoWindowContent = null;
@Override
public View getInfoContents(Marker marker) { if(mInfoWindowContent == null){
mInfoWindowContent = mInflater.inflate(R.layout.map_info, null);
} ImageView infoImage = (ImageView)mInfoWindowContent.findViewById(R.id.map_info_image);
infoImage.setImageResource(R.drawable.address);
TextView infoTitle = (TextView)mInfoWindowContent.findViewById(R.id.map_info_title);
infoTitle.setText(marker.getTitle()); TextView infoSnippet = (TextView)mInfoWindowContent.findViewById(R.id.map_info_snippet);
infoSnippet.setText(marker.getSnippet());
return mInfoWindowContent;
} @Override
public View getInfoWindow(Marker marker) {
return null;
}

6~8行,根据布局文件 res/layout/map_info.xml 填充一个View的布局

LayoutInflater mInflater = LayoutInflater.from(this); //this即activity的context

10~11行,设置图标

12~13行,设置title,marker.getTitle()取出marker中保存的title字符串

15~16行,设置snippet,marker.getSnippet()取出marker的snippet字符串

当点击标记弹出info window时,首先会跑到getInfoWindow(),如果返回null,就会跑到getInfoContents(),返回的View就显示到info window中。

4,根据经纬度发查地址,用snippet字段显示地址信息

首先监听marker点击事件

mMapView.setOnMarkerClickListener(this);

activity实现OnMarkerClickListener接口:

/* OnMarkerClickListener start */
@Override
public boolean onMarkerClick(Marker marker) {
if(mMarkerLoaded == false)
getAddressOfMarker();
return false;
}
/* OnMarkerClickListener end */

即,点击marker,在弹出info窗口前先去查询marker所在的经纬度的地理地址。

这个函数要返回false。如果返回true,则表示click事件被消费掉了,就不会再触发默认动作(即弹出info窗口)。

看下google的geocoder反解地址的过程:

private GetAddressTask mGetAddTack = null;

private void getAddressOfMarker(){
if(mGetAddTack != null){
mGetAddTack.cancel(true);
}
mGetAddTack = new GetAddressTask(this);
mGetAddTack.execute(mCarMarker.getPosition());
}

getAddressOfMarker函数中执行了一个异步小任务GetAddressTask,代码如下:

 private class GetAddressTask extends AsyncTask<LatLng, Void, String[]>{
Context mContext; public GetAddressTask(Context context) {
super();
mContext = context;
} @Override
protected void onPreExecute(){
mMarker.setTitle(getResources().getString(R.string.mapAddrLoading));
mMarker.setSnippet(" ");
if(mMarker.isInfoWindowShown())
mMarker.showInfoWindow();
} @Override
protected void onPostExecute(String[] result){
if(result == null)
return; if(mMarker != null){
if((result[1] != null) && (result[0] != null)){
mMarker.setTitle(result[0]);
mMarker.setSnippet(result[1]);
if(mMarker.isInfoWindowShown())
mMarker.showInfoWindow();
}
else{
mMarker.setTitle(getResources().getString(R.string.mapAddrTitle));
mMarker.setSnippet(getResources().getString(R.string.mapAddrUnknown));
if(mMarker.isInfoWindowShown())
mMarker.showInfoWindow();
} }
}
mMarkerLoaded = true;
} @Override
protected String[] doInBackground(LatLng... params) {
LatLng latlng = params[0];
String[] result = new String[2]; String urlString = "http://maps.google.com/maps/api/geocode/xml?language=zh-CN&sensor=true&latlng=";//31.1601,121.3962";
HttpGet httpGet = new HttpGet(urlString + latlng.latitude + "," + latlng.longitude);
HttpClient httpClient = new DefaultHttpClient(); InputStream inputStream = null;
HttpResponse mHttpResponse = null;
HttpEntity mHttpEntity = null;
try{
mHttpResponse = httpClient.execute(httpGet);
mHttpEntity = mHttpResponse.getEntity();
inputStream = mHttpEntity.getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String line = "";
String startTag = "<formatted_address>";
String endTag = "</formatted_address>";
while (null != (line = bufferedReader.readLine())){
if(isCancelled())
break;
line = line.trim();
String low = line.toLowerCase(Locale.getDefault());
if(low.startsWith(startTag)){
int endIndex = low.indexOf(endTag);
String addr = line.substring(startTag.length(), endIndex);
if((addr != null) && (addr.length() >0)){
result[1] = addr;
result[0] = getResources().getString(R.string.mapAddrTitle);
break;
}
}
}
}
catch (Exception e){
log("Exception in GetAddressTask doInBackground():" + e);
}
finally{
try{
if(inputStream != null)
inputStream.close();
}
catch (IOException e){
log("IOException in GetAddressTask doInBackground():" + e);
}
}
return result;
}
}

重点是41行开始的 doInBackground 函数,向google的geocoder发起一个http请求,请求格式如下:

http://maps.google.com/maps/api/geocode/xml?language=zh-CN&sensor=true&latlng=30.1601,121.3922

返回数据可以是JSON或XML,我这里用的是XML,语言中文zh-CN,latlng=纬度,经度

返回的XML脚本,是指定经纬度附近的有效地址,可能不只一个。我们只取第一个<formatted_address></formatted_address>标签中的字符串,保存在result中。

18行,在任务执行结束的onPostExcute函数中,调用marker.setSnippet(result[1])保存到snippet中,title则根据任务执行情况设置成合适的String。

26~28行,由于这是一个异步任务,地址取回的时候,info窗口可能已经显示出来了,这时调用showInfoWindow(),getInfoContents函数会重新跑一次,让窗口显示最新取到的title和snippet。

Google Map API v2 (三)----- 地图上添加标记(Marker),标记info窗口,即指定经纬度获取地址字符串的更多相关文章

  1. Android中Google地图路径导航,使用mapfragment地图上画出线路(google map api v2)详解

    在这篇里我们只聊怎么在android中google map api v2地图上画出路径导航,用mapfragment而不是mapview,至于怎么去申请key,manifest.xml中加入的权限,系 ...

  2. Google Map API v2 步步为营(一) ----- 初见地图

    官方文档:https://developers.google.com/maps/documentation/android/start?hl=zh-CN 先谷歌后百度.使用google的api基本上按 ...

  3. google map api v2的使用详细过程,图文并茂(原创)

    上一篇中说到怎么获取key,下面来介绍怎么使用key来显示google地图 步骤1:eclipse上打开android SDK Manager,安装google play services. 步骤2: ...

  4. 如何使用Google Map API开发Android地图应用

    两年前开发过的GoogleMap已经大变样,最近有项目要用到GoogleMap,重新来配置Android GoogleMap开发环境,还真是踩了不少坑. 一.下载Android SDK Manager ...

  5. Google Map API v2 (四)----- 导航路径

    仍然是建议个异步小任务 private GetPathTask mGetPathTask = null; private void getGuidePath(LatLng origin){ if(mG ...

  6. Google Map API抓取地图坐标信息小程序

    因为实验室需要全国城市乡镇的地理坐标,有Execl的地名信息,需要一一查找地方的经纬度.Google Map地图实验室提供自带的查找经纬度的方法,不过需要一个点一个点的手输入,过于繁琐,所以自己利用G ...

  7. Google Map API v2 步步为营 (二)----- Location

    接上篇. 改造一下MapsActivity: public class MapsActivity extends Activity implements LocationListener, InfoW ...

  8. Google Map API V2密钥申请

    之前用的都是v1,用的是MapView,好吧,仅仅能认命了.废话不再多说,開始android 的Google Maps Android API v2吧 之前參考了http://www.cnblogs. ...

  9. Google Map API v2 番外篇 关于gps位置偏差及修正方法探讨

    我的手机是M35C,在我自己的map activity中,通过gps获取到的经纬度比实际地址总是有500米左右的偏差. 在网上搜索了很多,都说这个是测绘局为了保密故意弄成这样的.gps全球定位系统获得 ...

随机推荐

  1. Qt 静态函数QMetaObject::connectSlotsByName(QObject * object)按命名规则自动connect,不需要手动connect

    看别人代码看到void on_MyWidget_slotTest(); 就郁闷了,没看到他代码里有connect 却能把信号和槽可以连接起来. 今日回顾书本发现该函所的nb之处. QMetaObjec ...

  2. Android Canvas使用drawBitmap绘制图片

    1.基本的绘制图片方法 //Bitmap:图片对象,left:偏移左边的位置,top: 偏移顶部的位置 drawBitmap(Bitmap bitmap, float left, float top, ...

  3. perl 初始化Hash

    Vsftp:/root/perl/6# cat a5.pl use Data::Dumper; my @arr=qw/a bc d /; my %rec=(); for $field (@arr){ ...

  4. 【2015年最新App Store退款流程详解】最详细AppStore退款流程图文教程

    本帖最后由 想吐就吐出来 于 2015-7-1 14:25 编辑 如果你一不小心买错了iOS软件,从App Store上下载了游戏或软件后悔了,那怎么办?可以退款吗?答案是可以的!苹果这点还是很人性化 ...

  5. pcDuino安装vnc进行远程控制

    准备工作: 已经刷好的 pcduino : 点此购买   可选用显示器或者用ssh连接,ssh连接参考 无显示器刷机与使用 1.安装x11vnc 输入下面的命令: sudo apt-get insta ...

  6. 改善C#程序的50种方法

    为什么程序已经可以正常工作了,我们还要改变它们呢?答案就是我们可以让它们变得更好.我们常常会改变所使用的工具或者语言,因为新的工具或者语言更富生产力.如果固守旧有的习惯,我们将得不到期望的结果.对于C ...

  7. 如何实现Azure虚拟网络中点到站VPN的自动重连

     在Windows Azure早期版本中,用户要在某台Azure平台之外的机器与Azure平台内部的机器建立专用连接,可以借助Azure Connect这个功能.当前的Azure版本,已经没有Az ...

  8. linux下用Apache一个IP多个网站多域名配置方法

    如有两个域名,分别是desk.xker.com和tool.xker.com,需把这两个域名都绑定到IP是219.13.34.32的服务器上 1.首先需在域名供应商管理页面指定域名和IP的对应关系 2. ...

  9. css权威指南(上)

    替换元素指用来替换内容的部分并非由文档内容直接表示,最常见的是图片,与之对应的就是非替换内容 <img src="how.gif"/> display展示的形式,常见的 ...

  10. Java web.xml加载顺序

     web.xml加载过程(步骤): 1.启动WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点:   <listener></listener&g ...