【android】利用Yahoo API完成天气预报


一、 代码展示

1. 文件布局: activity_realize_forecast.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
        <EditText
            android:inputType="number"
            android:id="@+id/input"
            android:layout_width="0dip"
            android:layout_height="wrap_content" 
            android:layout_weight="1"/>
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:text="@string/button_input"/>   
    </LinearLayout>
    
    <!-- 图像显示 -->
    <ImageView
        android:contentDescription="@string/image_description"
        android:id="@+id/iconOfWeather"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </ImageView>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
        <!-- 当前时间-->
        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            />        
        <!-- 天气状况 -->
        <TextView
            android:id="@+id/weather"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
        <!-- 温度  -->
	<TextView
            android:id="@+id/temp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    </LinearLayout>
</LinearLayout>



2.  天气预报主函数:RealizeForecast.java

package com.realize.andorid.realizeforecast;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class RealizeForecast extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_realize_forecast);
		
        Button submit = (Button) findViewById(R.id.btn);
        submit.setOnClickListener(new OnClickListener() {
        	@Override
            public void onClick(View arg0) {
                try {
                  /* 获取用户输入的城市代号 
                   * 从网址上可以获取对应城市代号:http://weather.yahoo.com/china/guangdong/shenzhen-2161853/
                   */
                   String city = ((EditText) findViewById(R.id.input))
                       .getText().toString();
                	
                    /* 如果用户没有输入,则弹出提示 */ 
                    if (city.equals(""))
                   {
                	Log.d("onClick", "city is null");
                        Toast.makeText(RealizeForecast.this, 
                        "请输入具体的城市代号!", 
                        Toast.LENGTH_LONG).show();
                        return;
                    }
                	   	
                    /*组成URL字符串*/
                    //http://weather.yahooapis.com/forecastrss?w=2162312&u=c
                    String queryString = "http://weather.yahooapis.com/forecastrss?w="
                			+ city + "&u=c";
                    /*将可能的空格替换为"%20"*/
                    URL aURL = new URL(queryString.replace(" ", "%20"));
                	
                    //URL aURL = new URL("http://weather.yahooapis.com/forecastrss?w=2161853&u=c");                   
                    /* 从SAXParserFactory获取SAXParser*/
                    SAXParserFactory spf = SAXParserFactory.newInstance();
                    SAXParser sp = spf.newSAXParser();

                    /* 从SAXParser得到XMLReader*/
                    XMLReader xr = sp.getXMLReader();

                    /*
                     * 创建YahooWeatherHandler,以便解析XML内容
                     */
                    YahooWeatherHandler ywh = new YahooWeatherHandler();
                    xr.setContentHandler(ywh);

                    /* 解析XML文件内容 */
                    xr.parse(new InputSource(aURL.openStream()));

                    /* 当前时间 */
                    TextView tv1 = (TextView)findViewById(R.id.time);
                    tv1.setText("当前时间:" + ywh.getCurrentTime());
                    
                    /* 天气状况 */
                    TextView tv2 = (TextView)findViewById(R.id.weather);
                    tv2.setText("天气状况:" + ywh.getCurrentCondition());
                    
                    /* 温度*/
                    TextView tv3 = (TextView)findViewById(R.id.temp);
                    tv3.setText("目前温度:" + ywh.getCurrentTemp());                    
                     
                    /* 获取图像地址,并显示  */
                    URL iconURL = new URL(ywh.getIconURL());
                    //URL iconURL = new URL("http://l.yimg.com/a/i/us/we/52/34.gif");
                	URLConnection conn = iconURL.openConnection();
                    conn.connect();
                    InputStream is = conn.getInputStream();
                    BufferedInputStream bis = new BufferedInputStream(is);
                    ImageView iv = (ImageView)findViewById(R.id.iconOfWeather);
                    Bitmap bm = null;
                    bm = BitmapFactory.decodeStream(bis);
                    iv.setImageBitmap(bm);
                    bis.close();
                    is.close();
                    
                    /* 清空输入框的内容 */
                    EditText et = (EditText)findViewById(R.id.input);
                    et.setText("");
               } catch (Exception e) {
                    Log.e("error",e.toString());
               }
        	}//end of onClick
        });//end of SetClick	
	}

}


3. 提取天气信息: YahooWeatherHandler.java

package com.realize.andorid.realizeforecast;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

/**
 * SAXHandler:用户从Yahoo Weather API返回的XML中提取当前天气信息
 */
public class YahooWeatherHandler extends DefaultHandler {    
     private String current_time;     //当前时间
     private String current_condition;//天气状况
     private String iconURL;          //天气图像
     private String current_temp;     //天气温度
     private boolean in_tag = false;  //标识是否解析到“description”
     
     public String getCurrentTime(){
    	 return this.current_time;
     }
     public String getCurrentCondition(){
    	 return this.current_condition;
     }
     public String getIconURL(){
    	 return this.iconURL;
     }
     public String getCurrentTemp(){
    	 return this.current_temp;
     }
     
     public void setCurrentTime(String current_time){
    	this.current_time = current_time;
     }
     public void setCurrentCondition(String condition) {
         this.current_condition = condition;
     }
     public void setIconURL(String iconURL) {
          this.iconURL = iconURL;
     }
     public void setCurrentTemp(String current_temp){
    	this.current_temp = current_temp;
     }
     
     @Override
     public void startDocument() throws SAXException {
   
     }

     @Override
     public void endDocument() throws SAXException {
          
     }

     @Override
     public void startElement(String namespaceURI, String localName,
               String qName, Attributes atts) throws SAXException {
    	 Log.d("weather", localName);
    	 if (localName.equals("condition"))
    	 {
    		 String textAttribute = atts.getValue("text");
    		 this.setCurrentCondition(textAttribute);
    		 
    		 String tempAttribute = atts.getValue("temp");
    		 this.setCurrentTemp(tempAttribute);  
    		 
    		 String dateAttribute = atts.getValue("date");
    		 this.setCurrentTime(dateAttribute);    		 
    	 }
    	 else if(localName.equals("description"))
    	 {
    		 in_tag = true;
    	 }
     }

     @Override
     public void endElement(String namespaceURI, String localName, String qName)
               throws SAXException {
    	 if(localName.equals("description"))
    	 {
    		 in_tag = false;
    	 }   	 

     }

     @Override
     public void characters(char ch[], int start, int length) 
     {
         /** 当遇到如下结构时被调用
          * <tag>characters</tag> 
          * <img src="http://l.yimg.com/a/i/us/we/52/34.gif"/><br />
          * 提取结果为:http://l.yimg.com/a/i/us/we/52/34.gif
          */
    	 if(this.in_tag)
    	 {
    		 String str = new String(ch, start, length);
    		 Log.d("characters", str);
    		 if (str.startsWith("<img src="))  //判断字符串str 是不是以字符串"<img src="开头
    		 {
    			 int index2 = str.indexOf("\"/><br />");
    			 String s2 = str.substring(10, index2);  //从str中提取字符串,从字符串str的第11个字符开始,第index2个字符结束
    			 Log.d("test_img S2", s2);
    			 this.setIconURL(s2); 
    		 }		   
    	 }
	}   	 
}


二、   验证结果

1.  yahoo API 深圳天气: http://weather.yahooapis.com/forecastrss?w=2161853&u=c 


2. 当没有输入城市代号,点击提交


3. 当输入“2161853”,点击提交


附:各个城市代号查询:http://weather.yahoo.com/china/guangdong/shenzhen-2161853/

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。