我的Android进阶之旅------>Android通过调用Webservice实现天气预报

通过这一篇文章WebService的读书笔记对Web Service的认识,现在来写一个小应用Android通过调用Webservice实现天气预报来加强对Web Srevice的学习

在开发天气预报的Android应用之前,首先需要找到一个可以对外提供天气预报的Web Service,通过搜索发现站点http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx可以对外提供天气预报的Web Service,因此程序会调用此站点的Web Service来实现天气预报。(注意:如果该站点的天气预报Web Service服务已经停止,那么本程序将无法正常调用Web Service,那么天气预报的功能自然也就失效啦)

好啦,现在开始step by step地实现该应用程序。

step1:新建Android项目MyWeather

我的Android进阶之旅------>Android通过调用Webservice实现天气预报_第1张图片

step2:获取并使用KSOAP包

在Android SDK中并没有提供调用WebService的库,因此,需要使用第三方的SDK来调用WebService。PC版本的WebService库非常丰富,但这些对Android来说过于庞大。适合手机的WebService客户端的SDK有一些,比较常用的是KSOAP2。

KSOAP2 地址:http://code.google.com/p/ksoap2-android/

我下载的最新的是: ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar

选择我们的项目,右键菜单中 Build Path –> Add External Archives… 增加这个下载的包

我的Android进阶之旅------>Android通过调用Webservice实现天气预报_第2张图片


我的Android进阶之旅------>Android通过调用Webservice实现天气预报_第3张图片


step3:设计应用的UI界面 /res/layout/main.xml



	
		
		
		
	
	
		
		
		
	
	
	
		
		
		
	
	
	
		
		
		
	
	
	
		
		
		
	
	


/res/values/strings.xml


    天气预报
    查询
    城市中文名
    省份
    城市


step3:编写调用Web Service的工具类 cn.roco.weather.WebServiceUtil.java

因为本程序主要需要调用如下三个Web Service操作:

a.获取省份:getRegionProvince方法

b.根据省份获取城市:getSupportCityString方法

c.根据城市获取天气:getWeather方法

为了让应用界面更加美观,可以访问http://www.webxml.com.cn/images/weather.zip下载各种天气图标,可以使用这些天气图标来美化应用。

package cn.roco.weather;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

public class WebServiceUtil
{
	// 定义Web Service的命名空间
	static final String SERVICE_NS = "http://WebXml.com.cn/";
	// 定义Web Service提供服务的URL
	static final String SERVICE_URL = 
		"http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx";

	// 调用远程 Web Service获取省份列表
	public static List getProvinceList()
	{
		/**
		 * 调用远程Web Service的getRegionProvince方法: 获得中国省份、直辖市、地区和与之对应的ID
		 * 
				黑龙江,3113
				吉林,3114
				辽宁,3115
				内蒙古,3116
				河北,3117
				河南,3118
				山东,3119
				山西,31110
				江苏,31111
				安徽,31112
				陕西,31113
				宁夏,31114
				甘肃,31115
				青海,31116
				湖北,31117
				湖南,31118
				浙江,31119
				江西,31120
				福建,31121
				贵州,31122
				四川,31123
				广东,31124
				广西,31125
				云南,31126
				海南,31127
				新疆,31128
				西藏,31129
				台湾,31130
				北京,311101
				上海,311102
				天津,311103
				重庆,311104
				香港,311201
				澳门,311202
				钓鱼岛,311203
				
		 */
		String methodName = "getRegionProvince";   //获得中国省份、直辖市、地区和与之对应的ID
		// 创建HttpTransportSE传输对象,该对象用于调用Web Service操作
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;
		// 使用SOAP1.1协议创建Envelop对象
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
			SoapEnvelope.VER11);
		// 实例化SoapObject对象,传入所要调用的Web Service的命名空间,Web Service方法名
		SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
		//将 soapObject对象设置为SoapSerializationEnvelope对象的传出SOAP消息
		envelope.bodyOut = soapObject;
		/**
		 *  因为什么这个网站是通过.NET对外提供Web Service的,
		 *  因此设置与.Net提供的Web Service保持较好的兼容性
		 */
		envelope.dotNet = true;
		try
		{
			// 调用Web Service
			ht.call(SERVICE_NS + methodName, envelope);
			if (envelope.getResponse() != null)
			{
				// 获取服务器响应返回的SOAP消息
				SoapObject result = (SoapObject) envelope.bodyIn;
				SoapObject detail = (SoapObject) result.getProperty(methodName
					+ "Result");
				// 解析服务器响应的SOAP消息。
				return parseProvinceOrCity(detail);
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		catch (XmlPullParserException e)
		{
			e.printStackTrace();
		}
		return null;
	}

	// 根据省份获取城市列表
	public static List getCityListByProvince(String province)
	{
		/**
		 *  调用的方法
		 *  获得支持的城市/地区名称和与之对应的ID
			输入参数:theRegionCode = 省市、国家ID或名称,返回数据:一维字符串数组。
			如:输入北京的theRegionCode:311101得到的返回结果为:
			
				北京,792
				昌平,785
				大兴,826
				房山,827
				怀柔,752
				门头沟,788
				密云,751
				平谷,756
				顺义,741
				通州,3409
				延庆,746
				海淀,742
				朝阳,3408
				丰台,795
				石景山,794
			
		 */
		String methodName = "getSupportCityString";  
		// 创建HttpTransportSE传输对象
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;
		// 实例化SoapObject对象
		SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
		// 添加一个请求参数
		soapObject.addProperty("theRegionCode", province);
		// 使用SOAP1.1协议创建Envelop对象
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
			SoapEnvelope.VER11);
		envelope.bodyOut = soapObject;
		// 设置与.Net提供的Web Service保持较好的兼容性
		envelope.dotNet = true;
		try
		{
			// 调用Web Service
			ht.call(SERVICE_NS + methodName, envelope);
			if (envelope.getResponse() != null)
			{
				// 获取服务器响应返回的SOAP消息
				SoapObject result = (SoapObject) envelope.bodyIn;
				SoapObject detail = (SoapObject) result.getProperty(methodName
					+ "Result");
				// 解析服务器响应的SOAP消息。
				return parseProvinceOrCity(detail);
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		catch (XmlPullParserException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	// 解析服务器响应的SOAP消息。
	private static List parseProvinceOrCity(SoapObject detail)
	{
		List result = new ArrayList();
		for (int i = 0; i < detail.getPropertyCount(); i++)
		{
			// 解析出每个省份
			result.add(detail.getProperty(i).toString().split(",")[0]);
		}
		return result;
	}
	// 根据城市获取城市具体天气情况
	public static SoapObject getWeatherByCity(String cityName)
	{
		/**
		 * 获得天气预报数据        输入参数:城市/地区ID或名称,返回数据:一维字符串数组。
		       如:输入theCityCode:792(北京,792)得到的返回结果为:
		       This XML file does not appear to have any style information associated with it. The document tree is shown below.
				
						直辖市 北京
						北京
						792
						2013/04/30 03:47:53
						今日天气实况:气温:14℃;风向/风力:东风 2级;湿度:21%
						空气质量:良;紫外线强度:强
						
						穿衣指数:建议着薄型套装等春秋过渡装。年老体弱者宜着套装。但昼夜温差较大,注意适当增减衣服。 过敏指数:天气条件极易诱发过敏,易过敏人群尽量减少外出,外出宜穿长衣长裤并佩戴好眼镜和口罩,外出归来时及时清洁手和口鼻。 运动指数:天气较好,但由于风力较大,推荐您在室内进行低强度运动,若在户外运动请注意避风。 洗车指数:适宜洗车,未来持续两天无雨天气较好,适合擦洗汽车,蓝天白云、风和日丽将伴您的车子连日洁净。 晾晒指数:天气不错,适宜晾晒。赶紧把久未见阳光的衣物搬出来吸收一下太阳的味道吧! 旅游指数:天气较好,风稍大,但温度适宜,是个好天气哦。很适宜旅游,您可以尽情地享受大自然的无限风光。 路况指数:天气较好,路面比较干燥,路况较好。 舒适度指数:白天天气晴好,您在这种天气条件下,会感觉早晚凉爽、舒适,午后偏热。 空气污染指数:气象条件有利于空气污染物稀释、扩散和清除,可在室外正常活动。 紫外线指数:紫外线辐射强,建议涂擦SPF20左右、PA++的防晒护肤品。避免在10点至14点暴露于日光下。
						
						4月30日 晴
						11℃/27℃
						北风3-4级转无持续风向微风
						0.gif
						0.gif
						5月1日 晴转多云
						12℃/25℃
						无持续风向微风
						0.gif
						1.gif
						5月2日 多云转晴
						13℃/26℃
						无持续风向微风
						1.gif
						0.gif
						5月3日 多云转阴
						11℃/23℃
						无持续风向微风
						1.gif
						2.gif
						5月4日 阴转多云
						14℃/27℃
						无持续风向微风
						2.gif
						1.gif											
				

		 */
		String methodName = "getWeather";
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
			SoapEnvelope.VER11);
		SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
		soapObject.addProperty("theCityCode", cityName);
		envelope.bodyOut = soapObject;
		// 设置与.Net提供的Web Service保持较好的兼容性
		envelope.dotNet = true;
		try
		{
			ht.call(SERVICE_NS + methodName, envelope);
			SoapObject result = (SoapObject) envelope.bodyIn;
			SoapObject detail = (SoapObject) result.getProperty(methodName
				+ "Result");
			return detail;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
}

step4:编写适配器,用于显示数据 cn.roco.weather.ListAdapter.java

package cn.roco.weather;

import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ListAdapter extends BaseAdapter
{
	private Context context;
	private List values;
	
	public ListAdapter(Context context , List values)
	{
		this.context = context;
		this.values = values;
	}

	@Override
	public int getCount()
	{
		return values.size();
	}

	@Override
	public Object getItem(int position)
	{
		return values.get(position);
	}

	@Override
	public long getItemId(int position)
	{
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		TextView text = new TextView(context);
		text.setText(values.get(position));
		text.setTextSize(20);
		text.setTextColor(Color.BLACK);
		return text;
	}
}

step5:程序的主应用cn.roco.weather.MyWeather.java

package cn.roco.weather;

import java.util.List;

import org.ksoap2.serialization.SoapObject;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.AdapterView.OnItemSelectedListener;

public class MyWeather extends Activity
{
	private Spinner provinceSpinner;
	private Spinner citySpinner;
	private ImageView todayWhIcon1;
	private ImageView todayWhIcon2;
	private TextView textWeatherToday;
	private ImageView tomorrowWhIcon1;
	private ImageView tomorrowWhIcon2;
	private TextView textWeatherTomorrow;
	private ImageView afterdayWhIcon1;
	private ImageView afterdayWhIcon2;
	private TextView textWeatherAfterday;
	private TextView textWeatherCurrent;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		todayWhIcon1 = (ImageView) findViewById(R.id.todayWhIcon1);
		todayWhIcon2 = (ImageView) findViewById(R.id.todayWhIcon2);
		textWeatherToday = (TextView) findViewById(R.id.weatherToday);
		tomorrowWhIcon1 = (ImageView) findViewById(R.id.tomorrowWhIcon1);
		tomorrowWhIcon2 = (ImageView) findViewById(R.id.tomorrowWhIcon2);
		textWeatherTomorrow = (TextView) findViewById(R.id.weatherTomorrow);
		afterdayWhIcon1 = (ImageView) findViewById(R.id.afterdayWhIcon1);
		afterdayWhIcon2 = (ImageView) findViewById(R.id.afterdayWhIcon2);
		textWeatherAfterday = (TextView) findViewById(R.id.weatherAfterday);
		textWeatherCurrent = (TextView) findViewById(R.id.weatherCurrent);

		// 获取程序界面中选择省份、城市的Spinner组件
		provinceSpinner = (Spinner) findViewById(R.id.province);
		citySpinner = (Spinner) findViewById(R.id.city);
		// 调用远程Web Service获取省份列表
		List provinces = WebServiceUtil.getProvinceList();
		ListAdapter adapter = new ListAdapter(this, provinces);
		// 使用Spinner显示省份列表
		provinceSpinner.setAdapter(adapter);
		// 当省份Spinner的选择项被改变时
		provinceSpinner.setOnItemSelectedListener(new OnItemSelectedListener()
		{
			@Override
			public void onItemSelected(AdapterView source, View parent,
				int position, long id)
			{
				// 根据省份获取城市列表
				List cities = WebServiceUtil
					.getCityListByProvince(provinceSpinner.getSelectedItem()
						.toString());
				ListAdapter cityAdapter = new ListAdapter(MyWeather.this,
					cities);
				// 使用Spinner显示城市列表
				citySpinner.setAdapter(cityAdapter);
			}

			@Override
			public void onNothingSelected(AdapterView arg0)
			{
			}
		});
		// 当城市Spinner的选择项被改变时
		citySpinner.setOnItemSelectedListener(new OnItemSelectedListener()
		{
			@Override
			public void onItemSelected(AdapterView source, View parent,
				int position, long id)
			{
				//展现天气预报的具体数据
				showWeather(citySpinner.getSelectedItem().toString());
			}

			@Override
			public void onNothingSelected(AdapterView arg0)
			{
			}
		});
	}
	//展现天气预报的具体数据
	private void showWeather(String city)
	{
		String weatherToday = null;
		String weatherTomorrow = null;
		String weatherAfterday = null;
		String weatherCurrent = null;
		int iconToday[] = new int[2];
		int iconTomorrow[] = new int[2];
		int iconAfterday[] = new int[2];
		// 获取远程Web Service返回的对象
		SoapObject detail = WebServiceUtil.getWeatherByCity(city);// 根据城市获取城市具体天气情况
		// 获取天气实况
		weatherCurrent = detail.getProperty(4).toString();
		// 解析今天的天气情况
		String date = detail.getProperty(7).toString();
		weatherToday = "今天:" + date.split(" ")[0];
		weatherToday = weatherToday + "\n天气:" + date.split(" ")[1];
		weatherToday = weatherToday + "\n气温:"
			+ detail.getProperty(8).toString();
		weatherToday = weatherToday + "\n风力:"
			+ detail.getProperty(9).toString() + "\n";
		iconToday[0] = parseIcon(detail.getProperty(10).toString());
		iconToday[1] = parseIcon(detail.getProperty(11).toString());
		// 解析明天的天气情况
		date = detail.getProperty(12).toString();
		weatherTomorrow = "明天:" + date.split(" ")[0];
		weatherTomorrow = weatherTomorrow + "\n天气:" + date.split(" ")[1];
		weatherTomorrow = weatherTomorrow + "\n气温:"
			+ detail.getProperty(13).toString();
		weatherTomorrow = weatherTomorrow + "\n风力:"
			+ detail.getProperty(14).toString() + "\n";
		iconTomorrow[0] = parseIcon(detail.getProperty(15).toString());
		iconTomorrow[1] = parseIcon(detail.getProperty(16).toString());
		// 解析后天的天气情况
		date = detail.getProperty(17).toString();
		weatherAfterday = "后天:" + date.split(" ")[0];
		weatherAfterday = weatherAfterday + "\n天气:" + date.split(" ")[1];
		weatherAfterday = weatherAfterday + "\n气温:"
			+ detail.getProperty(18).toString();
		weatherAfterday = weatherAfterday + "\n风力:"
			+ detail.getProperty(19).toString() + "\n";
		iconAfterday[0] = parseIcon(detail.getProperty(20).toString());
		iconAfterday[1] = parseIcon(detail.getProperty(21).toString());
		// 更新当天的天气实况
		textWeatherCurrent.setText(weatherCurrent);
		// 更新显示今天天气的图标和文本框
		textWeatherToday.setText(weatherToday);
		todayWhIcon1.setImageResource(iconToday[0]);
		todayWhIcon2.setImageResource(iconToday[1]);
		// 更新显示明天天气的图标和文本框
		textWeatherTomorrow.setText(weatherTomorrow);
		tomorrowWhIcon1.setImageResource(iconTomorrow[0]);
		tomorrowWhIcon2.setImageResource(iconTomorrow[1]);
		// 更新显示后天天气的图标和文本框
		textWeatherAfterday.setText(weatherAfterday);
		afterdayWhIcon1.setImageResource(iconAfterday[0]);
		afterdayWhIcon2.setImageResource(iconAfterday[1]);
	}

	// 工具方法,该方法负责把返回的天气图标字符串,转换为程序的图片资源ID。
	private int parseIcon(String strIcon)
	{
		if (strIcon == null)
			return -1;
		if ("0.gif".equals(strIcon))
			return R.drawable.a_0;
		if ("1.gif".equals(strIcon))
			return R.drawable.a_1;
		if ("2.gif".equals(strIcon))
			return R.drawable.a_2;
		if ("3.gif".equals(strIcon))
			return R.drawable.a_3;
		if ("4.gif".equals(strIcon))
			return R.drawable.a_4;
		if ("5.gif".equals(strIcon))
			return R.drawable.a_5;
		if ("6.gif".equals(strIcon))
			return R.drawable.a_6;
		if ("7.gif".equals(strIcon))
			return R.drawable.a_7;
		if ("8.gif".equals(strIcon))
			return R.drawable.a_8;
		if ("9.gif".equals(strIcon))
			return R.drawable.a_9;
		if ("10.gif".equals(strIcon))
			return R.drawable.a_10;
		if ("11.gif".equals(strIcon))
			return R.drawable.a_11;
		if ("12.gif".equals(strIcon))
			return R.drawable.a_12;
		if ("13.gif".equals(strIcon))
			return R.drawable.a_13;
		if ("14.gif".equals(strIcon))
			return R.drawable.a_14;
		if ("15.gif".equals(strIcon))
			return R.drawable.a_15;
		if ("16.gif".equals(strIcon))
			return R.drawable.a_16;
		if ("17.gif".equals(strIcon))
			return R.drawable.a_17;
		if ("18.gif".equals(strIcon))
			return R.drawable.a_18;
		if ("19.gif".equals(strIcon))
			return R.drawable.a_19;
		if ("20.gif".equals(strIcon))
			return R.drawable.a_20;
		if ("21.gif".equals(strIcon))
			return R.drawable.a_21;
		if ("22.gif".equals(strIcon))
			return R.drawable.a_22;
		if ("23.gif".equals(strIcon))
			return R.drawable.a_23;
		if ("24.gif".equals(strIcon))
			return R.drawable.a_24;
		if ("25.gif".equals(strIcon))
			return R.drawable.a_25;
		if ("26.gif".equals(strIcon))
			return R.drawable.a_26;
		if ("27.gif".equals(strIcon))
			return R.drawable.a_27;
		if ("28.gif".equals(strIcon))
			return R.drawable.a_28;
		if ("29.gif".equals(strIcon))
			return R.drawable.a_29;
		if ("30.gif".equals(strIcon))
			return R.drawable.a_30;
		if ("31.gif".equals(strIcon))
			return R.drawable.a_31;
		return 0;
	}
}


step6:AndroidManifest.xml



	
	
		
			
				
				
			
		

	

	
 

step7:部署应用,观看运行效果

我的Android进阶之旅------>Android通过调用Webservice实现天气预报_第4张图片我的Android进阶之旅------>Android通过调用Webservice实现天气预报_第5张图片

我的Android进阶之旅------>Android通过调用Webservice实现天气预报_第6张图片



附注:本应用的源码在:http://pan.baidu.com/share/link?shareid=419671&uk=805959799

关于Web Service的应用还可以查看Android通过调用Webservice实现手机号码归属地查询进行学习



==================================================================================================

作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!

转载请保留原文地址:http://blog.csdn.net/ouyang_peng

==================================================================================================


你可能感兴趣的:(移动开发,java,ui)