首页 > 作文

手机天气

更新时间:2023-03-22 15:02:25 阅读: 评论:0

处女座和什么座最配-简易红包灯笼

手机天气
2023年3月22日发(作者:鱼块怎么炸好吃)

使用GoogleWeatherAPI制作一个简单的天气预报应用

大家在使用android手机的时候,肯定都是用过天气预报的应用,market上面已经有了

不少很成熟的产品.当然,作为开发者而言,一定会对这种应用的开发很感兴趣,我们能不

能自己来写一款类似的应用呢?答案当然是可以的,而且非常的简单,下面我就来给大家

介绍一下.

首先,要开发一款天气预报应用,一定要有一个web服务端来提供数据,这个数据源

我们自己肯定是没办法弄的,所以就需要一个第三方机构为我们提供天气数据.这种机构其

实有很多,不过大多数都是收费的,当然这些收费的数据源提供的数据会更加丰富详细.如

果不想花钱去购买这些收费的数据服务,我们还有另一种替代方案-就是使用免费的天气数

据,这篇文章了为大家介绍一个Google提供的天气API,通过浏览器访问下面的链接:

/ig/api?hl=zh-cn&weather=Beijing

如果你的浏览器可以直接显示XML文档,那么就会得到类似下面这样的数据:

...

...

当然,这里只给大家列出一个片断,完整的数据大家可以自己用浏览器来查看.上面这

段数据给我们提供了气温的数字和文字描述,还给我们提供了一幅表示当天天气状况的图片。

对于我们这个简单的天气应用,这些数据已经足够了。

有了数据之后,我们就开始开发吧,怎么建项目就不用我说了吧,呵呵。虽然这个应用

很简单,但我们还需要把结构稍微整理一下,我们需要用一个实体类来表示天气数据:

publicclassWeather{

privateStringday;

privateStringlowTemp;

privateStringhighTemp;

privateStringimageUrl;

privateStringcondition;

}

我们通过XML文档提供的数据格式来定义我们实体类,这里面包含了,当天是周几,

最低气温,最高气温,天气图片的地址,和天气状况的文字描述.为了节省篇幅getter和

tter方法就省略了,现在我们已经把我们需要的数据封装好了.

接下来我们需要解析XML数据,将服务器返回给我们的XML格式的数据,转换成程序

比较好操作的对象,我们可以使用SAX来解析XML文档,关于SAX的更多细节,不是本篇

文章要讨论的内容,不过为了让大家好理解,还是简单的叙述一下.

SAX其实是解析XML文档的一种方法,一般处理XML数据有两种方法,一种是将数据

先解析为一种树形结构,然后我们再来在这个结构上访问数据,这种方法是我们通常会直接

想到的,而SAX则采用了另外一种方法,这种方法简单来说就是,当解析器遍历XML文档

的时候,会给提供我们一些回调函数,比如遇到起始标签,遇到结束标签,或是遇到标签中

的文字等等,这是一种基于事件的解析方式,所以我们需要一个类来处理这些事件,并且将

需要的数据保存下来,就产生了下面这段代码:

publicclassXmlHandlerextendsDefaultHandler{

privateListweatherList;

privatebooleaninForcast;

privateWeathercurrentWeather;

publicListgetWeatherList(){

returnweatherList;

}

publicvoidtWeatherList(ListweatherList){

rList=weatherList;

}

publicXmlHandler(){

weat上方山云水洞 herList=newArrayList();

inForcast=fal;

}

@Override

publicvoidstartElement(Stringuri,StringlocalName,StringqName,

Attributesattributes)throwsSAXException{

StringtagName=()!=0?loc刘贺是谁的儿子 alName:qName;

tagName=rCa();

if(("forecast_conditions")){

inForcast=true;

currentWeather=newWeather();

}

if(inForcast){

if(("day_of_week")){

(ue("data"));

}elif(("low")){

Temp(ue("data"));

}elif(("high")){

hTemp(ue("data"));

}elif(("icon")){

geUrl(ue("data"));

}elif(("condition")){

dition(ue("data"));

}

}

}

@Override

publicvoidendElement(Stringuri,StringlocalName,StringqName)

throwsSAXException{

StringtagName=()!=0?localName:qName;

tagName=rCa();

if(("forecast_conditions")){

inForcast=fal;

(currentWeather);

}

}

}

startElement方法,代表遇到起始标签,我们在这里得到了标签名,如果遇到

forecast_conditions标签,我们就会标记一下,并且创建一个天气实体对象,下面的if语句

中,判断了是否在forecast_conditions标签内,如果在的话,就把它里面相应的属性提取出

来。

endElement方法,代表遇到结束标签,我们的代码里,如果遇到forecast_conditions

标签,那么就证明当前这条天气数据已经解析完成,所以我们将该实体对象保存到List列表

中,以便以后使用。

通过这段讲解,相信大家对SAX已经有了一个初步的了解,要使用SAX的话,还需要

它的jar包,因为它不是标准库中的东西,如果需要更详细的内容,可以参看的我一篇帖子:

/?tid=33212&highlight=

现在终于处理完数据了,其实这个程序本身并不是很复杂,大半的代码都用在了解析数

据上面。下面开始进入我们的主程序,首先来看看我们的布局文件:

<?xmlversion="1.0"encoding="utf-8"?>

xmlns:android="/apk/res/android"

android:orien感恩节用英语怎么说 tation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

>

android:id="@+id/txCity"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="9"

/>

android:id="@+id/btnSearch"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="2"

android:text="查询"

/>

android:id="@+id/table"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:stretchColumns="1,2,3,4"

>

顶部定义了一个文本框,和一个查询按钮,下面是一个表格布局,这个非常简单,应该

不用我再展开说明了吧,呵呵。

下面就到了最后一个部分,也是程序中主要的部分,我们的Activity代码,首先,我们

需要定义一个查询天气的方法:

privatevoidarchWeather(Stringcity){

SAXParrFactoryspf=tance();

try{

//此处为SAX解析部分

SAXParrsp=Parr();

XMLReaderreader=Reader();

XmlHandlerhandler=newXmlHandler();

tentHandler(handler);

URLurl=newURL("/ig/api?hl=zh-cn&weather="+

(city));

InputStreamis=ream();

InputStreamReaderisr=newInputStreamReader(is,"GBK");

InputSourcesource=newInputSource(isr);

(source);

ListweatherList=therList();

TableLayouttable=(TableLayout)findViewById();

AllViews();

for(Weatherweather:weatherList){

TableRowrow=newTableRow(this);

outParams(newLayoutParams(_PARENT,

_CONTENT));

vity(_VERTICAL);

ImageViewimg=newImageView(this);

geDrawable(loadImage(geUrl()));

imumHeight(80);

w(img);

TextViewday=newTextView(this);

t(());

vity(_HORIZONTAL);

w(day);

TextViewtemp=newTextView(this);

t(Temp()+"℃-"+hTemp()+"℃

");

vity(_HORIZONTAL);

w(temp);

TextViewcondition=newTextView(this);

t(dition());

vity(_HORIZONTAL);

w(condition);

w(row);

}

}catch(Exceptione){

r(this)

.tTitle("解析错误")

.tMessage("获取天气数据失败,请稍候再试。")

.tNegativeButton("确定",null)

.show();

}

}

大家看看代码应该就差不多都明白了,这个方法开始的部分,我们使用SAX相关的API

来处理XML数据,有几处地方需要说明一下:

InputStream弟子规入则孝 Readerisr=newInputStreamReader(is,"GBK");

由于API返回给我们的中文是国标编码的,而SAX默认会以UTF-8来处理得到的数据,

所以我们要在输入流中指定一下编码格式。接下来调用(source);方法来解析我们

的输入源,这里的一连串SAX方法调用,表达的目的应该很清楚了,相信以大家的水平,即

使以前没有用过,也能很容易看明白,当然,如果是在看不懂,可以先参考一下我的那篇帖

子,补充一下基础知识。接下来的代码应该就比较简单了,都是一些控件的操作,当我们解

析完数据,得到对象集合之后,我们就能够遍历这个集合,然西游记感悟 后将每条记录,用一个TableRow

来包含上。在异常处理中,我们弹出一个对话框,来告诉用户本次请求中出现了问题。注意

到我们在处理图片的时候用到了一个loadImage方法,这个是我们自己定义的工具方法,用

来通过图片的url来加载相应图片:

privateDrawableloadImage(Stringurl){

try{

FromStream((InputStream)new

URL("/"+url).getContent(),"test");

}catch(MalformedURLE空腹喝咖啡好不好 xceptione){

Log.e("exception",sage());

}catch(IOExceptione){

Log.e("exception",sage());

}

returnnull;

}

这个方法做的事情就是将google返回给我们的url,转换为android中的Drawable对象,

仔细观察的人在刚才看xml数据的时候可能注意到了,google给我们提供的图片地址是相对

于它的站点根目录的相对路径,所以我们在请求图片的时候,还需要加上google站点的前

缀。这样,我们获取天气数据的逻辑就彻底完成了。

当然,基本功能虽然实现了,但作为一个应用,我们是不是应该把它的体验做的更好呢,

如果我们在应用主线程中调用这个方法,就会造成同步网络通信,这个可是客户端应用程序

最忌讳的东西,在通信过程中用户的界面会被完全阻塞住,非常影响体验。所以我们一定需

要一个异步的通信机制来完成请求数据的过程。异步操作的话,就需要另外一个线程来获取

数据并且更新视图。而在android中,处于安全方面的原因,非GUI线程是不能操作用户的

界面控件的。也就是说我们没有办法在另外一个单独的线程中直接给我们的Table增加子控

件。

但这并不代表我们就没有办法了,android为我们提供了一种叫做Handler的机制来异

步更新我们的界面元素,与线程不同的是,它需要一个Message来激活它,当然,这个听

起来好像挺复杂的,不过使用起来真的很简单,就来看看下面的代码吧:

private兔子用英语怎么说 TextViewtxCity;

privateButtonbtnSearch;

privateHandlerweatherHandler;

privateDialogprogressDialog;

privateTimertimer;

@Override

publicvoidonCreate(BundlesavedInstanceState){

te(savedInstanceState);

tContentView();

timer=newTimer();

txCity=(TextView)findViewById();

btnSearch=(Button)findViewById(rch);

progressDialog=r(this)

.tTitle("读取数据中")

.tMessage("正在加载数据,请稍等")

.create();

weatherHandler=newHandler(){

@Override

publicvoidhandleMessage(Messagemsg){

finalStringcityName=t().toStri简历介绍 ng();

archWeather(cityName);

();

}

};

lickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewv){

();

le(newTimerTask(){

@Override

publicvoidrun(){

Messagemsg=newMessage();

get(weatherHandler);

Target();

}

},100);

}

});

}

我们定义了几个私有成员,这其中有TextView,Button,Handler,Dialog和Timer。在

onCreate方法开始时,我们做了一些初始化操作,下面对需要讲解的地方简单说明一下:

progressDialog=r(this)

.tTitle("读取数据中")

.tMessage("正在加载数据,请稍等")

.create();

这段代码定义了一个对话框,用来提示用户,程序正在请求天气数据,这里使用里Builder

方式来构建对话框,关于这个对话框构造机制,可以参看我的另一篇帖子:

/?tid=32248&highlight=

本文发布于:2023-03-22 15:02:24,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/a1af1367e01dd41281b056d5e447d95f.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:手机天气.doc

本文 PDF 下载地址:手机天气.pdf

标签:手机天气
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图