位置识别这是实际应用经常应用的消息,特别是很多商家,通过了解用户位置,给用户提供特别的产品或是商场的推荐。其中用户可能发送两种类型的消息:
1.微信地理位置信息
2.路名、标志性建筑或是商场名称
1.微信地理位置消息
认识一下,微信地理位置消息,包含一些什么信息
< xml >
< ToUserName > <![CDATA[ toUser ]]> </ ToUserName >
< FromUserName > <![CDATA[ fromUser ]]> </ FromUserName >
< CreateTime > 1351776360 </ CreateTime >
< MsgType > <![CDATA[ location ]]> </ MsgType >
< Location_X > 23.134521 </ Location_X >
< Location_Y > 113.358803 </ Location_Y >
< Scale > 20 </ Scale >
< Label > <![CDATA[ 位置信息 ]]> </ Label >
< MsgId > 1234567890123456 </ MsgId >
</ xml >
包含的主要信息有经度纬度和Label的位置。可以根据label中描述的位置信息,提供给用户对应的服务。也可根据用户的经度纬度信息,提供你最近的产品或是有地域性的产品。
public class WeChatLocationMessage {
private String toUserName;
private String fromUserName;
private String createTime;
private String msgType;
private String locationx;
private String localtiony;
private String scale;
private String label;
private String msgId;
public static WeChatLocationMessage getWeChatLocationMessage(String xml){
XStream xstream = new XStream( new DomDriver());
WeChatLocationMessage message = null ;
xstream.alias( " xml " , WeChatLocationMessage. class );
xstream.aliasField( " ToUserName " , WeChatLocationMessage. class , " toUserName " );
xstream.aliasField( " FromUserName " , WeChatLocationMessage. class , " fromUserName " );
xstream.aliasField( " CreateTime " , WeChatLocationMessage. class , " createTime " );
xstream.aliasField( " MsgType " , WeChatLocationMessage. class , " msgType " );
xstream.aliasField( " Location_X " , WeChatLocationMessage. class , " locationx " );
xstream.aliasField( " Location_Y " , WeChatLocationMessage. class , " localtiony " );
xstream.aliasField( " Scale " , WeChatLocationMessage. class , " scale " );
xstream.aliasField( " Label " , WeChatLocationMessage. class , " label " );
xstream.aliasField( " MsgId " , WeChatLocationMessage. class , " msgId " );
message = (WeChatLocationMessage)xstream.fromXML(xml);
return message;
}
// getter and setter
} 本文利用百度的地图API,查找最近的银行做为示例。
public String getPalace(String query,String lat,String lng) throws ClientProtocolException, IOException{
HttpClient httpClient = new DefaultHttpClient();
String url = palceRequestUrl(query,lat,lng);
logger.log(Level.INFO, url);
HttpGet httpget = new HttpGet(url);
ResponseHandler < String > responseHandler = new BasicResponseHandler();
String responseBody = httpClient.execute(httpget, responseHandler);
logger.log(Level.INFO, " baidu response: " + responseBody);
return responseBody;
}
public String palceRequestUrl(String query,String lat,String lng) throws UnsupportedEncodingException {
String url = WeChatConstant.BASEURL + " place/search?query= " + URLEncoder.encode(query, " UTF-8 " ) + " &key= "
+ WeChatConstant.MAPKEY + " &location= " + lat + " , " + lng + " &radius=2000 " + " &output= " + WeChatConstant.OUTPUTFORMAT;
return url;
} 输出的结果
< PlaceSearchResponse >
< status > OK </ status >
< results >
< result >
< name > 中国工商银行东长安街支行 </ name >
< location >
< lat > 39.915891 </ lat >
< lng > 116.41867 </ lng >
</ location >
< address > 东城区东长安街1号东方广场西三办公楼1楼 </ address >
< uid > a025683c73033c35a21de987 </ uid >
< detail_url > http: // api.map.baidu.com/place/detail?uid=a025683c73033c35a21de987&amp;output=html&amp;source=placeapi
</ detail_url >
< tag > 银行,王府井 / 东单 </ tag >
</ result >
</ results >
</ PlaceSearchResponse >
接下来,把百度地图反映出来的最近位置信息,以图文消息的格式展示给微信用户
public static String getWeChatReplyNewsMessageByBaiduPlace(List < BaiduPlaceResponse > placeList, double lat, double lng,String userName, int size){
WeChatReplyNewsMessage newsMessage = new WeChatReplyNewsMessage();
List < Item > items = new ArrayList < Item > ();
StringBuffer strBuf = new StringBuffer();
logger.log(Level.INFO, " placeList count= " + placeList.size());
newsMessage.setItems(items);
if (placeList.size() > size){
newsMessage.setArticleCount(size);
}
else {
newsMessage.setArticleCount(placeList.size());
}
logger.log(Level.INFO, " article count= " + newsMessage.getArticleCount());
newsMessage.setCreateTime( new Date().getTime() + "" );
newsMessage.setMsgType( " news " );
newsMessage.setFuncFlag( " 0 " );
newsMessage.setToUserName(userName);
newsMessage.setFromUserName(WeChatConstant.FROMUSERNAME);
for ( int i = 0 ;i < newsMessage.getArticleCount();i ++ ){
BaiduPlaceResponse place = placeList.get(i);
Double distance = GeoUtil.DistanceOfTwoPoints(Double.valueOf(place.getLng()), Double.valueOf(place.getLat()), lng, lat, GaussSphere.Beijing54);
Item item = new Item();
item.setTitle(place.getName() + " [ " + distance + " 米] " + " \n " + place.getAddress() + " \n " + place.getTelephone());
item.setPicUrl( "" );
item.setUrl(place.getDetailUrl());
item.setDescription( "" );
items.add(item);
}
logger.log(Level.INFO, " newMessage= " + newsMessage.toString());
strBuf = strBuf.append(getWeChatNewsMessage(newsMessage));
return strBuf.toString();
}
public static String getWeChatNewsMessage(WeChatReplyNewsMessage newsMessage){
XStream xstream = new XStream( new DomDriver());
xstream.alias( " xml " , WeChatReplyNewsMessage. class );
xstream.aliasField( " ToUserName " , WeChatReplyNewsMessage. class , " toUserName " );
xstream.aliasField( " FromUserName " , WeChatReplyNewsMessage. class , " fromUserName " );
xstream.aliasField( " CreateTime " , WeChatReplyNewsMessage. class , " createTime " );
xstream.aliasField( " MsgType " , WeChatReplyNewsMessage. class , " msgType " );
xstream.aliasField( " ArticleCount " , WeChatReplyNewsMessage. class , " articleCount " );
xstream.aliasField( " Content " , WeChatReplyNewsMessage. class , " content " );
xstream.aliasField( " FuncFlag " , WeChatReplyNewsMessage. class , " funcFlag " );
xstream.aliasField( " Articles " , WeChatReplyNewsMessage. class , " items " );
xstream.alias( " item " , Item. class );
xstream.aliasField( " Title " , Item. class , " title " );
xstream.aliasField( " Description " , Item. class , " description " );
xstream.aliasField( " PicUrl " , Item. class , " picUrl " );
xstream.aliasField( " Url " , Item. class , " url " );
return xstream.toXML(newsMessage);
}
2.路名、标志性建筑或是商场名称
对路名、标志性建筑等信息,方法还是通过第三方地图信息,确定输入的位置信息的经度纬度。
本文使用百度地图API,确定所查找的位置的经度和纬度。
public String getGeoCode(String query) throws ClientProtocolException, IOException{
HttpClient httpClient = new DefaultHttpClient();
String url = geoCodeRequestUrl(query);
logger.log(Level.INFO, url);
HttpGet httpget = new HttpGet(url);
ResponseHandler < String > responseHandler = new BasicResponseHandler();
String responseBody = httpClient.execute(httpget, responseHandler);
logger.log(Level.INFO, " baidu response: " + responseBody);
return responseBody;
}
public String geoCodeRequestUrl(String query) throws UnsupportedEncodingException{
String url = WeChatConstant.BASEURL + " geocoder?address= " + URLEncoder.encode(query, " UTF-8 " ) + " &key= "
+ WeChatConstant.MAPKEY + " &output= " + WeChatConstant.OUTPUTFORMAT;
return url;
}
确定了经度和纬度,问题就变成和第1种消息类型一致了,根据经度纬度去做相应处理。
本文的代码较长,提供源代码下载。
原创文章,转载请注明: 转载自http://www.qiyadeng.com/