我们在第(7)介绍过获取微信用户GPS地理位置信息的方法,有两种,当时给出了第一种实现源代码,今天给出第二种获取方式源码。先来回顾一下以前的内容。
一、应用举例
基于位置的应用太多太多了,比如:
查找附近的人;
查找附近的商家;
计算与指定的人或商家的距离;
使用百度地图、腾讯地图、阿里地图的api接口,在地图上打标,实现可视化地图;
计算配送费等等等等。
二、获取微信用户位置信息方式
微信公众号可以通过两种方式获取微信用户的GPS位置,
一是普通消息方式,用户在微信app内主动向公众号发出位置信息,如下图所示:
二是微信app自动提醒微信用户是否上传位置信息,用户允许后,可以定时向公众号发送位置信息,如下图所示:
该种方式需要在微信公众号内配置接口权限(见下图),打开自动接受用户信息,可以选择每隔几分钟发送,也可以选择每次进入使用公众号时发送,具体看应用需要,粉丝量大时,发送越频繁,服务器负荷越大。
三、微信服务器发送事件格式
用户发送的位置事件,经微信服务器处理后,形成如下XML格式发到你的服务器:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[LOCATION]]></Event>
<Latitude>23.137466</Latitude>
<Longitude>113.352425</Longitude>
<Precision>119.385040</Precision>
</xml>
四、代码实现
在接收到微信服务器发来的事件之后,首先由指定的接口网页AccessWx.aspx对事件类型进行判别,然后交给指定的事件处理类处理和回应。在本系列文章第1篇介绍的AccessWx.aspx.cs中开始部分引入命名空间using QinMing.Weixin.EventHandlerLocation;
并完善下面处理LOCATION这一段,增加本篇给出的上报位置事件处理环节。
else if(MsgType == "event")
{
string Event = xn.SelectSingleNode("//Event").InnerText;
if(Event == "subscribe")
{
//对用户关注公众号的事件处理,使用QinMing.Weixin.EventHandlerSubscribe命名空间下的SubscribeEventDeal类
SubscribeEventDeal ued = new SubscribeEventDeal();
Response.Write(ued.DealResult(weixinXML));
}
else if(Event == "unsubscribe")
{
//对用户取消关注公众号的事件处理,使用QinMing.Weixin.EventHandlerUnSubscribe命名空间下的UnSubscribeEventDeal类
UnSubscribeEventDeal ued = new UnSubscribeEventDeal();
Response.Write(ued.DealResult(weixinXML));
}
else if(Event == "LOCATION")
{
//对用户上报的位置信息事件处理,使用QinMing.Weixin.EventHandlerLocation命名空间下的LocationEventDeal类
LocationEventDeal ued = new LocationEventDeal();
Response.Write(ued.DealResult(weixinXML));
}
//其他处理
}
在命名空间QinMing.Weixin.EventHandlerLocation下新建一个类LocationEventDeal,用来处理微信服务器发来的gps位置事件。记得类源码文件要放在App_Code目录下!下面是上报位置事件处理源码:
QinMingWeixinEventHandlerLocation.cs文件内容如下:
using System;
using System.Web;
using System.Xml;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using QinMing.Config;
using QinMing.Tools;
namespace QinMing.Weixin.EventHandlerLocation
{
//事件消息处理:上报位置信息
public class LocationEventDeal :System.Web.UI.Page
{
public string DealResult(string weixinXML)
{
string content = DealLocation(weixinXML);
return content;
}
public string DealLocation(string weixinXML)
{
string content1="";
string strresponse = "";
XmlDocument doc = new XmlDocument();
doc.LoadXml(weixinXML);
XmlNodeList list = doc.GetElementsByTagName("xml");
XmlNode xn = list[0];
string FromUserName = xn.SelectSingleNode("//FromUserName").InnerText; //关注用户的加密后openid
string ToUserName = xn.SelectSingleNode("//ToUserName").InnerText; //公众微信号原始ID
string MsgType=xn.SelectSingleNode("//MsgType").InnerText;
string Event=xn.SelectSingleNode("//Event").InnerText;
string Latitude = xn.SelectSingleNode("//Latitude").InnerText;
string Longitude = xn.SelectSingleNode("//Longitude").InnerText;
string Precision = xn.SelectSingleNode("//Precision").InnerText;
//更新微信用户经纬度位置信息
GetLocation(FromUserName, Latitude, Longitude, Precision);
//保存上报位置信息事件
SaveEvent(FromUserName, ToUserName, Latitude, Longitude, Precision);
//给管理员发送粉丝上报位置事件通知
QinMing.WeixinTemplateMessage.SendTemplateMessage.SendRemindMsg("管理员openid", "粉丝上报位置信息提醒" + FromUserName, "http://www.yourweb.com/Weixin/DisplayUser.aspx?open_id=" + FromUserName);
return strresponse;
}
//进入公众号后,自动提示是否允许使用粉丝地理位置,同意的发此事件,是用户主动向公众号发送位置信息。
public void GetLocation(string FromUserName, string Latitude, string Longitude , string Precision)
{
SqlConnection conn = new SqlConnection(QinMingConfig.DatabaseConnStr);
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "update weixin_user_info set latitude='" + Latitude + "',longitude='" + Longitude + "',"
+ "precision='" + Precision + "' where open_id='" + FromUserName + "' and remove_flag = '已关注' ";
cmd.ExecuteScalar();
if (conn.State == ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
}
//保存事件信息。
public void SaveEvent(string FromUserName, string ToUserName,string Latitude, string Longitude , string Precision)
{
SqlConnection conn = new SqlConnection(QinMingConfig.DatabaseConnStr);
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "insert into weixin_recv_event (msg_type,event_type,open_id,gh_id,recv_time,latitude,longitude,precision) "
+ "values ('event','LOCATION','" + FromUserName + "','" + ToUserName + "',getdate(),'" + Latitude + "','" + Longitude + "','" + Precision + "') ";
//QinMingTools.WriteLog("sql语句:", cmd.CommandText);
cmd.ExecuteScalar();
if (conn.State == ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
}
}
}