位置識(shí)別這是實(shí)際應(yīng)用經(jīng)常應(yīng)用的消息,特別是很多商家,通過(guò)了解用戶位置,給用戶提供特別的產(chǎn)品或是商場(chǎng)的推薦。其中用戶可能發(fā)送兩種類型的消息:
1.微信地理位置信息
2.路名、標(biāo)志性建筑或是商場(chǎng)名稱
1.微信地理位置消息
認(rèn)識(shí)一下,微信地理位置消息,包含一些什么信息
<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>
包含的主要信息有經(jīng)度緯度和Label的位置。可以根據(jù)label中描述的位置信息,提供給用戶對(duì)應(yīng)的服務(wù)。也可根據(jù)用戶的經(jīng)度緯度信息,提供你最近的產(chǎn)品或是有地域性的產(chǎn)品。
首先根據(jù)微信的地理位置信息,定義WeChatLocationMessage類,并能把Xml轉(zhuǎn)換為WeChatLocationMessage對(duì)象
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;
}
輸出的結(jié)果
<PlaceSearchResponse>
<status>OK</status>
<results>
<result>
<name>中國(guó)工商銀行東長(zhǎng)安街支行</name>
<location>
<lat>39.915891</lat>
<lng>116.41867</lng>
</location>
<address>東城區(qū)東長(zhǎng)安街1號(hào)東方廣場(chǎng)西三辦公樓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>
接下來(lái),把百度地圖反映出來(lái)的最近位置信息,以圖文消息的格式展示給微信用戶
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.路名、標(biāo)志性建筑或是商場(chǎng)名稱
對(duì)路名、標(biāo)志性建筑等信息,方法還是通過(guò)第三方地圖信息,確定輸入的位置信息的經(jīng)度緯度。
本文使用百度地圖API,確定所查找的位置的經(jīng)度和緯度。
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;
}
確定了經(jīng)度和緯度,問(wèn)題就變成和第1種消息類型一致了,根據(jù)經(jīng)度緯度去做相應(yīng)處理。
3.源代碼
本文的代碼較長(zhǎng),提供源代碼下載。
WeChatDemo下載