最近,项目忙得很,公司里杂事很多都跑到我这里,搞得我也不能专心的做项目,索性,今天抽空,玩了一玩谷歌的天气预报服务。相信通过这篇文章,能让大家了解在.net CF下如何发起一个http访问请求(WebRequest),以及处理请求到的数据,比如xml数据、图片数据等。当然,在此分享也是娱乐一把,边走边说吧!
开始,我们需要了解一下,谷歌的这个服务API,通过也即你在浏览器输入http://www.google.com/ig/api?weather=Kunming,看看什么效果,哈哈,一个xml结构的数据显示在网页中,这就是今天的主角儿!其实,WM通常获取这类数据是通过Webservice,但是也有些信息是通过之前那种http方式提供的,所以,如果我们的WM程序要完成天气预报的获取,至少要完成如下几个步骤:
- 发起一个http请求:HttpWebRequest
- 处理这个请求返回的数据:HttpWebResponse
- 把这些数据组织成可读性强的形式:UI
很幸运,.net CF提供了关于http请求和处理的相关类,当然,它对xml文档操作的支持也是非常的人性化了,在开动Coding之前,先来普及一下某些知识:
————http请求,看图!
并且,附上一篇好文:HTTP请求流程(一)----流程简介,希望大家能够耐心的去了解,毕竟待会儿的代码中就会涉及某些知识,哈哈。
好了,开始惊心动魄的Coding吧,嘿嘿!
首先,用vs2008建立一个以c#语言为基础的智能设备应用程序,模拟器用5.0 ppc即可,.net cf版本么,2.0吧~~~~~
然后我们来设计如下的一个用户界面:
几个lable,用来存放天气数据,一个pictureBox用来存放天气图标。两个按钮,一个用来开启主要功能,另一个退出,简单吧!哈哈。到此界面完成了。我们来看看具体的业务代码,双击获取信息按钮,加入如下代码:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{
int i = 0 ;
// 开始从xml文件中提取天气信息到Lable
XmlNodeList ggNodeList = GoogleWeatherAPI_Parser( @" http://www.google.com/ig/api?weather=Kunming " ).SelectNodes( " xml_api_reply/weather/current_conditions " );
lblTempC.Text = ggNodeList.Item(i).SelectSingleNode( " temp_c " ).Attributes[ " data " ].InnerText; // 获取温度信息
lblHumidity.Text = ggNodeList.Item(i).SelectSingleNode( " humidity " ).Attributes[ " data " ].InnerText; // 获取湿度信息
lblCurtWeather.Text = ggNodeList.Item(i).SelectSingleNode( " condition " ).Attributes[ " data " ].InnerText; // 获取天气状况信息
lblwind_condition.Text = ggNodeList.Item(i).SelectSingleNode( " wind_condition " ).Attributes[ " data " ].InnerText; // 获取风向信息
// 获取远程图片的url地址,进行组装
string picPath = " http://www.google.com " + ggNodeList.Item(i).SelectSingleNode( " icon " ).Attributes[ " data " ].InnerText; // 获取远程图片地址
picBoxWeather.Image = GetPicImage(picPath); // 通过GetPicImage方法,将远程图片转化为.net CF图片控件所能使用的Image对象!
}
代码很好理解,也看到.net cf对xml数据的操作还是比较方便的,我们读取了选定的节点数据,赋值给lable控件,应该是一目了然了吧。我就不再赘述,下面要说说两个地方,第一,那个GoogleWeatherAPI_Parser方法;第二,GetPicImage方法。
首先,GoogleWeatherAPI_Parser方法主要是进行一个HttpWebRequest的发起,并且相应这个请求的回应,接受xml数据,具体代码如下:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/// 从远程地址中,获取返回的xml文件结构体
/// </summary>
/// <param name="baseUrl"> 远程url </param>
/// <returns></returns>
private static XmlDocument GoogleWeatherAPI_Parser( string baseUrl)
{
HttpWebRequest gg_Request;
HttpWebResponse gg_Response = null ;
XmlDocument gg_XMLdoc = null ;
try
{
gg_Request = (HttpWebRequest)WebRequest.Create( string .Format(baseUrl));
gg_Request.UserAgent = @" Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100413 Firefox/3.6.4 " ;
gg_Response = (HttpWebResponse)gg_Request.GetResponse();
gg_XMLdoc = new XmlDocument();
gg_XMLdoc.Load(gg_Response.GetResponseStream());
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
gg_Response.Close();
return gg_XMLdoc;
}
哈,很简单吧,就是发起一个Http请求,把一些请求信息加入到Header中,比如地域性息、浏览器版本等……经过测试,如果你的地域是美国,那么返回的信息是英文的,当然,其他国家暂时没有测试哦……
下面,来看看GetPicImage方法,因为谷歌返回的那个xml数据中,天气图片是一个远程的url地址,对于PictureBox来说,不可能直接使用的,但是,经查,只要把这个图片地址进行HttpWebRequest一下,然后接受返回的Stream,再把此Stream通过Image的FromStream方法进行接收,就可以了。
实际上,.net CF下的Image类,只有FromHbitmap方法,看看此方法接受的参数,就知道杯具了,看来不能直接使用那个请求后返回的Stream,要做一个转换,如何转换呢,请看代码:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/// 从远程url地址,还原image对象
/// </summary>
/// <param name="picPath"> 远程图片地址 </param>
/// <returns></returns>
private Image GetPicImage( string picPath)
{
Bitmap bit;
Image imagePic;
HttpWebRequest gg_Request;
HttpWebResponse gg_Response = null ;
gg_Request = (HttpWebRequest)WebRequest.Create(picPath);
gg_Response = (HttpWebResponse)gg_Request.GetResponse();
bit = new Bitmap(gg_Response.GetResponseStream());
imagePic = Image.FromHbitmap(bit.GetHbitmap());
gg_Response.Close();
return imagePic;
}
现在是不是明白很多了呢,我们先通过一个Bitmap对象,接受这个ResponseStream的内容,然后,再利用Bitmap的GetHbitmap方法,就得到了一个Hbitmap对象,刚好可以用来“填充”一个Image对象,而填充后的Image对象,就可以被PictureBox所使用。也许,这也是这篇文章中相对难度较大的地方,在此和大家分享一下。
Ok,说了这么多,系统主要功能模块代码和思路都有了,接下来要看看运行效果如何,如下图:
恩,风和日丽,湿度刚好!不愧是昆明啊~呵呵,好了,今天的文章就到此为止。谢谢!
参考文章: