Android 版本的天气预报
Android 版本的天气预报
今天主要学习的就是天气预报,调用google的weather的API接口可以实现未来四天的天气预报,本程序主要应用的方法是从SAX 解析XML文档,嗯对了,还有一个第三方的jar包sax2r2.jar,因为,首先,要开发一款天气预报应用,一定要有一个web服务端来提供数据,这个数据源我们自己肯定是没办法弄的,所以就需要一个第三方机构为我们提供天气数据.这种机构其实有很多,不过大多数都是收费的,当然这些收费的数据源提供的数据会更加丰富详细.如果不想花钱去购买这些收费的数据服务,我们还有另一种替代方案-就是使用免费的天气数据,这篇文章了为大家介绍一个Google 提供的天气API接着看看实现的过程1.先看看布局,一个编辑框,一个按钮,一个表格布局
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical"
- android:background="@drawable/bg">
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="其输入你要查询天气的城市:" />
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <EditText
- android:id="@+id/editcity"
- android:layout_width="100dp"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/buttonsearch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="查询"
- />
- </LinearLayout>
- <TableLayout
- android:id="@+id/weathertable"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:stretchColumns="1"
- >
- <!-- stretchColumns="1" TableLayout所有行的第二列为扩展列。
- 也就是说如果每行都有三列的话,剩余的空间由第二列补齐 -->
- </TableLayout>
- </LinearLayout>
- package com.wang.xml;
- import java.util.ArrayList;
- import java.util.List;
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- public class XmlHandler extends DefaultHandler{
- private List<weatherSetGet> weatherlist;
- private boolean Forcast;
- private weatherSetGet weathercurrent;
- //声明列表函数
- public List<weatherSetGet> getWeatherList(){
- return weatherlist;
- }
- public void setWeatherlist(List<weatherSetGet> weatherlist){
- this.weatherlist=weatherlist;
- }
- //构造函数
- public XmlHandler(){
- weatherlist=new ArrayList<weatherSetGet>();
- Forcast=false;
- }
- // 结束解析XML的文档中的元素
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- //
- String tagname =localName.length()!=0?localName:qName;
- //转换这个字符串以较低的情况下,使用规则的用户的默认语言环境。
- tagname=tagname.toLowerCase();
- // 如果标记的名字是forecast_conditions则结束解析
- if (tagname.equals("forecast_conditions")) {
- //预测为假
- Forcast =false;
- //添加指定的对象在这个列表中
- weatherlist.add(weathercurrent);
- }
- }
- // 开始解析XML的文档中的元素
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- String tagname=localName.length()!=0?localName:qName;
- tagname=tagname.toLowerCase();
- // 如果标记的名字是forecast_conditions开始解析
- if (tagname.equals("forecast_conditions")) {
- Forcast=true;
- weathercurrent=new weatherSetGet();
- }
- if (Forcast) {
- if (tagname.equals("day_of_week")) {
- //设置值为得到的解析数据的值
- weathercurrent.setDay(attributes.getValue("data"));
- } else if( tagname.equals("low")) {
- weathercurrent.setLow(attributes.getValue("data"));
- } else if( tagname.equals("high")) {
- weathercurrent.setHigh(attributes.getValue("data"));
- } else if( tagname.equals("icon")) {
- weathercurrent.setImage(attributes.getValue("data"));
- } else if( tagname.equals("condition")) {
- weathercurrent.setCondition(attributes.getValue("data"));
- }
- }
- }
- }
- package com.wang.xml;
- public class weatherSetGet {
- private String day;
- private String low;
- private String high;
- private String image;
- private String condition;
- //创建get和set的对象函数
- public String getDay() {
- return day;
- }
- public void setDay(String day) {
- this.day = day;
- }
- public String getLow() {
- return low;
- }
- public void setLow(String low) {
- this.low = low;
- }
- public String getHigh() {
- return high;
- }
- public void setHigh(String high) {
- this.high = high;
- }
- public String getImage() {
- return image;
- }
- public void setImage(String image) {
- this.image = image;
- }
- public String getCondition() {
- return condition;
- }
- public void setCondition(String condition) {
- this.condition = condition;
- }
- }
- package com.wang;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.net.URL;
- import java.net.URLEncoder;
- import java.util.List;
- import java.util.Timer;
- import java.util.TimerTask;
- import javax.xml.parsers.SAXParser;
- import javax.xml.parsers.SAXParserFactory;
- import org.xml.sax.InputSource;
- import org.xml.sax.XMLReader;
- import com.wang.xml.XmlHandler;
- import com.wang.xml.weatherSetGet;
- import android.R.color;
- import android.R.layout;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.app.Dialog;
- import android.graphics.Color;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.Gravity;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup.LayoutParams;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ImageView;
- import android.widget.TableLayout;
- import android.widget.TableRow;
- import android.widget.TextView;
- public class WeatherTestDemoActivity extends Activity {
- private EditText edcity;
- private Button searchBtn;
- private Handler weatherHandler;
- private Dialog dialog;
- private Timer time;
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- time =new Timer();
- edcity=(EditText)findViewById(R.id.editcity);
- searchBtn=(Button)findViewById(R.id.buttonsearch);
- // 进度对话框,等待资源的下载。。
- dialog=new AlertDialog.Builder(this)
- .setTitle("读取数据中.....").setMessage("请稍等,正在加载数据...").create();
- //这个处理程序的默认构造函数associates的队列为当前线程。如果不是这一个,这个处理程序不能接收消息。
- weatherHandler =new Handler(){
- @Override
- public void handleMessage(Message msg) {
- // 等到从编辑框里输入的城市名称,并赋值个cityname
- final String cityname=edcity.getText().toString();
- // 调用seachcityweather进行天气查询
- seachcityweather(cityname);
- //隐藏进度对话框
- dialog.hide();
- }
- };
- //为按钮添加点击事件
- searchBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //显示进度对话框
- dialog.show();
- //对单个的计划任务执行指定的延时之后。
- time.schedule(new TimerTask() {
- @Override
- public void run() {
- /***
- *定义了一个消息,其中包含一个描述和任意的数据对象,
- *可以发送给一个处理程序。
- *这个对象包含两个额外的int字段和一个额外的对象字段
- *,允许您不分配在许多情况下。 虽然构造函数的信息是公共的,
- *最好的办法就是其中的一个叫Message.obtain()
- *或Handler.obtainMessage()方法,
- *它将把他们从池中回收的对象。
- * ****/
- //声明一个消息对象
- Message msg=new Message();
- //设置消息目标为weatherHandler
- msg.setTarget(weatherHandler);
- msg.sendToTarget();
- }
- }, 100);
- }
- });
- }
- protected void seachcityweather(String cityname) {
- //SAX解析,SAXParserFactory可以使应用程序配置并获取一个基于SAX的解析器解析来的XML文档
- SAXParserFactory factory=SAXParserFactory.newInstance();
- try {
- /**SAXParser
- * 这类包装解析器接口,这个接口是由XMLReader取代。
- * 为便于过渡,这类继续支持相同的名称和接口以及支持新方法。
- * 这个类的实例可以获得newSAXParser()方法。
- * 一旦获取该类的实例,XML可以解析来自各种输入源。
- * 这些输入来源是InputStreams、文件、url和SAX InputSources
- **/
- //实力化SAXParser 得到xml解析的对象getXMLReader
- SAXParser sp=factory.newSAXParser();
- XMLReader reader=sp.getXMLReader();
- //调用XmlHandler 生成一个对象
- XmlHandler handler=new XmlHandler();
- /**让应用程序可以注册一个事件处理程序的内容。
- * 如果应用程序不注册一个内容处理程序,
- * 所有内容事件报道的SAX解析器会悄悄地忽略。
- * 应用程序可以注册一个新的或不同的处理程序在中间的一个解析,
- * SAX解析器必须立即开始使用新的处理程序。***/
- reader.setContentHandler(handler);
- //得到解析的天气的资源+你所需要解析的城市
- URL url=new URL("http://www.google.com/ig/api?hl=zh-cn&weather=" + URLEncoder.encode(cityname));
- /****
- * 读取数据从源输入流转换成字符通过提供的字符转换器。
- * 默认的编码是取自“文件。编码”的系统属性。
- * InputStreamReader包含一个缓冲区读取的字节数从源流并将其转化成字符需要。
- * 缓冲区的大小是8 K
- */
- //打开输入流
- InputStream inputStream=url.openStream();
- //转换成国家标准扩展码GBK
- InputStreamReader inputStreamReader=new InputStreamReader(inputStream,"GBK");
- /**** InputSource
- * 这个类允许SAX应用程序封装输入源的信息在一个单独的对象,
- * 这可能包括一个公共标识符、系统标识符,字节流(可能有一个指定的编码),和转义字符或字符流。
- *
- **/
- //声明一个对象
- InputSource source=new InputSource(inputStreamReader);
- /******
- * 应用程序可以使用这个方法来指导读者开始的XML解析一个XML文档
- * 从任何有效的输入源(一个字符流,字节流,或一个URI)。
- * 应用程序可能无法调用该方法虽然解析过程中
- * (他们应该创建一个新的XMLReader相反嵌套的每个XML文档)。
- * 一旦一个解析完成,应用程序可以重用相同的XMLReader对象,
- * 可能使用不同的输入源
- * XMLReader的配置对象(如处理器绑定和价值观的确立对功能的标志和属性)是未受完成解析,
- * 除非那方面的定义显式地指定配置的其他行为*******/
- reader.parse(source);
- //得到天气列表
- List<weatherSetGet> weatherlist=handler.getWeatherList();
- //实力化表格布局
- TableLayout tableLayout=(TableLayout)findViewById(R.id.weathertable);
- //删除viewGroup中的子视图
- tableLayout.removeAllViews();
- for (weatherSetGet weather:weatherlist) {
- TableRow row=new TableRow(this);
- //设置布局参数与此相关的视图。
- //这些供应参数到父的这个视图指定应该如何安排。
- row.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
- //垂直居中
- row.setGravity(Gravity.CENTER_VERTICAL);
- ImageView imageView=new ImageView(this);
- //下载图片并绘制
- imageView.setImageDrawable(loadImage(weather.getImage()));
- ///z最小高度
- imageView.setMinimumHeight(50);
- row.addView(imageView);
- TextView day=new TextView(this);
- // 文本内容和颜色
- day.setText(weather.getDay());
- day.setTextColor(Color.RED);
- day.setGravity(Gravity.CENTER_HORIZONTAL);
- //添加视
- row.addView(day);
- TextView tv=new TextView(this);
- tv.setText(weather.getLow()+"℃ - "+weather.getHigh()+"℃ ");
- tv.setTextColor(Color.RED);
- //添加视图
- row.addView(tv);
- TextView condition=new TextView(this);
- //水平居中
- condition.setGravity(Gravity.CENTER_HORIZONTAL);
- //添加视图
- row.addView(condition);
- tableLayout.addView(row);
- }
- } catch (Exception e) {
- // 解析错误时候弹出对话框
- new AlertDialog.Builder(this)
- .setTitle("解析出错啦!!!")
- .setMessage("获取天气数据失!!!请重试!!!")
- .setNegativeButton("确定", null).show();
- }
- }
- //加载天气图片资源
- private Drawable loadImage(String image) {
- try {
- //从输入流InputStream绘图并得到返回其内容的资源是指由该URL。
- //默认情况下,返回一个InputStream,或null如果内容类型的响应是未知的
- return Drawable.createFromStream((InputStream)new URL("http://www.google.com/"+image).getContent(), "测试...");
- } catch (Exception e) {
- Log.e("exception", e.getMessage());
- }
- return null;
- }
- }
- <!-- 添加联网的权限 -->
- ;uses-permission android:name="android.permission.INTERNET"/>
android 中@override和如何导入第三方jar包(见 )这个里面有关于解决导入第三方jar包的问题,不过里面是导入的高德地图的jar包,其实sax2r2.jar的jar包导入过程和高德地图的方法过程一样,因为都是第三方jar包
7,运行效果入下:
8.如果想下载源码请点击下面的网址:
免费下载地址在 http://linux.bkjia.com/
用户名与密码都是www.bkjia.com
具体下载目录在 /2012年资料/8月/3日/Android 版本的天气预报/
评论暂时关闭