安卓实现天气预报效能

安卓实现天气预报功能

此篇文章主要针对初学者,讲述了如何如何利用webservice访问天气预报接口获取网络数据,对返回结果的处理,以及如何利用Handler更新主线程UI。先看效果图:

安卓实现天气预报效能
接下来看主程序:
package com.example.getweather;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;



import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
	
	private EditText cityname;
	private Button btn;
	private TextView textView;
    private final int duration=Toast.LENGTH_LONG;
    private String theCityName;
    private String result;
    private ProgressDialog progressDialog;
    
    @SuppressLint("HandlerLeak")
	private Handler handler=new Handler(){
		@Override
		public void handleMessage(Message msg) {
			progressDialog.dismiss();
			switch (msg.what) {
			case 1:		
				LinearLayout myLayout=(LinearLayout) findViewById(R.id.myLinearLayout);
				PraseWeaTherUtil p=new PraseWeaTherUtil(result.substring(8, result.length()-2));
				textView.setText("所在省/直辖市:"+p.getProvince());
				myLayout.addView(getTextView("所在市:"+p.getCity()));
				myLayout.addView(getTextView("时间:"+p.getTime()));
				myLayout.addView(getTextView("温度:"+p.getNowDayTemperature()));
				myLayout.addView(getTextView("今日天气:"+p.getNowDayWeaTher()));
				myLayout.addView(getTextView("天气实况:"+p.getNowDayWeaTher_Detail()));
				myLayout.addView(getTextView("风力:"+p.getWind_power()));
				myLayout.addView(getTextView("明日天气:"+p.getWeaTher_Detail2()));
				myLayout.addView(getTextView("温度:"+p.getTemperature2()));
				myLayout.addView(getTextView("后天天气:"+p.getWeaTher_Detail3()));
				myLayout.addView(getTextView("温度:"+p.getTemperature3()));
				break;
			case -1:
				Toast.makeText(getApplicationContext(), "获取数据失败", duration).show();
				break;
			}
		}
    };
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		textView=(TextView)findViewById(R.id.textview);
		cityname=(EditText)findViewById(R.id.cityname);
		btn=(Button)findViewById(R.id.btn);
		btn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				theCityName=cityname.getText().toString();
				if(null==theCityName||"".equals(theCityName)){
					Toast.makeText(getApplicationContext(), "请填写要查询的城市", duration).show();
					return;
				}
				progressDialog=new ProgressDialog(MainActivity.this);
				progressDialog.setMessage("正在获取天气数据...");
				progressDialog.show();
				new Thread(new GetWeatherTask(theCityName)).start();
			}
		});
		
	}

	private class GetWeatherTask implements Runnable{
		
		String theCityName="";
		
		public GetWeatherTask(String theCityName) {
			super();
			this.theCityName = theCityName;
		}

		@Override
		public void run() {
			try{
				result=getRemoteInfo(theCityName);
				handler.obtainMessage(1).sendToTarget();
			}catch(Exception e){
				e.printStackTrace();
				handler.obtainMessage(-1).sendToTarget();
			}
		}
		
	}
	
	private TextView getTextView(String content){
		TextView tv=new TextView(this);
		tv.setTextSize(16);
		tv.setTextColor(Color.parseColor("#000000"));
		tv.setText(content);
		return tv;
	}
	
	/**
	 * 通过webservice获取城市天气
	 * @param theCityName
	 * @return
	 */
	public String getRemoteInfo(String theCityName) {
		//http://WebXml.com.cn/getWeatherbyCityName
		// 命名空间
		String nameSpace = "http://WebXml.com.cn/";
		// 调用的方法名称
		String methodName = "getWeatherbyCityName";
		// EndPoint通常是将WSDL地址末尾的"?WSDL"去除后剩余的部分
		String endPoint = "http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx";
		// SOAP Action通常为命名空间 + 调用的方法名称
		String soapAction = "http://WebXml.com.cn/getWeatherbyCityName";

		// 指定WebService的命名空间和调用的方法名
		SoapObject rpc = new SoapObject(nameSpace, methodName);

		// 设置需调用WebService接口需要传入的两个参数mobileCode、userId
		rpc.addProperty("theCityName", theCityName);

		// 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);

		envelope.bodyOut = rpc;
		// 设置是否调用的是dotNet开发的WebService
		envelope.dotNet = true;
		// 等价于envelope.bodyOut = rpc;
		envelope.setOutputSoapObject(rpc);

		HttpTransportSE transport = new HttpTransportSE(endPoint);
		try {
			// 调用WebService
			transport.call(soapAction, envelope);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 获取返回的数据
		SoapObject object = (SoapObject) envelope.bodyIn;
		
		return object.getProperty(0).toString();
	}

}

获取网络数据属于耗时操作,需要放在子线程进行,通过消息处理机制可以更新主线程UI,代码中我们看到有一个PraseWeaTherUtil类,这个是自己根据返回的天气数据格式写的一个解析类,此天气接口返回的数据形式如:anyType={string=xxx;string=xxx;},它并不是json格式,所以需要自己写一个解析类,当然我这个解析类比较简单只是截取了一部分数据,大家也可以根据自己的需求,写一个自定义的解析类,下面截取部分代码:
public PraseWeaTherUtil(String result) {
		super();
		String results[]=result.replace("string=", "").split(";");
		this.province=results[0];
		this.city=results[1];
		this.time=results[4];
		this.nowDayTemperature=results[5];
		this.nowDayWeaTher=results[6];
		this.nowDayWeaTher_Detail=results[10];
		this.WeaTher_Detail2=results[13];
		this.temperature2=results[12];
		this.WeaTher_Detail3=results[18];
		this.temperature3=results[17];
				
	}

详细解释已经在代码中写的很清楚,最后不要忘了写入访问网络权限,大家可以下载我的源码参考:
 
http://download.csdn.net/detail/baiyuliang2013/7091937