web service是实现异构程序之间调用的一种机制。它通过一种xml格式的特殊文件来描述调用的方法,参数,及返回值等,这种格式的xml文件被称为WSDL(web 服务描述语言),其采用的通信协议是SOAP(简单对象访问协议)。可以参考w3school上对xml的介绍。google 提供了实现web service访问的android中的KSOAP jar包。本程序中使用的是ksoap2.4的版本,版本不同其中的某些类有点差异。
本程序通过Ksoap实现简单的读取天气预报。首先将ksoap.jar的包加入到工程。在我的资源中有上传ksoap2.4的包。下载地址http://download.csdn.net/detail/gw_li/4465580。
首先是布局文件用一个ListView来显示获取的省份的信息。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:id="@+id/city" android:layout_width="fill_parent"
android:layout_height="fill_parent"></ListView>
</RelativeLayout>
建立City的类来解析,显示获取的城市,天气的信息,通过使用ksoap 调用http://WebXml.com.cn/网站的一个免费的天气预报Web Service。把整个类分开来看,首先是调用的获取省份的方法,获得所有省份。获取的都是xml的文件,然后在本地解析为需要的信息。获取的xml文件图中所示,获取的是省份的信息和编号,然后通过对xml整个字符串解析得到我们需要的信息。
// soap命名空间
String Namespace = "http://WebXml.com.cn/";
// 调用的方法
String method = "getRegionProvince";
// 请求的url
String url = "http://webService.webxml.com.cn/WebServices/WeatherWS.asmx";
// 实例化soapObject
SoapObject request = new SoapObject(Namespace, method);
// 获得序列的envelop
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
// 注册envelop
envelope.bodyOut = request;
(new MarshalBase64()).register(envelope);
// android传输对象
AndroidHttpTransport http = new AndroidHttpTransport(url);
http.debug = true;
try {
http.call("http://WebXml.com.cn/getRegionProvince", envelope);
if (envelope.getResponse() != null) {
String str = envelope.bodyIn.toString();
// 记录第一个String的位置
int start = str.indexOf("string");
// 记录最后一个;的位置
int end = str.lastIndexOf(";");
// 取start和end-3之间的字符串
String temp = str.substring(start, end - 3);
// 以;为分隔符划分数组
String[] test = temp.split(";");
List<String> city = new ArrayList<String>();
for (int i = 0; i < test.length; i++) {
if (i == 0) {
temp = test[i].substring(7);
} else {
temp = test[i].substring(8);
}
int index = temp.indexOf(",");
city.add(temp.substring(0, index));
}
通过getWeather函数传入要查看的省份的名称来获得天气信息的xml文件。获得的xml文件如图。也需要解析成需要的信息。
// 使用Apache Http来获得天气信息
public String getWeather(String name) {
String url = "http://webService.webxml.com.cn/WebServices/WeatherWS.asmx/getWeather";
HttpPost request = new HttpPost(url);
List<NameValuePair> paras = new ArrayList<NameValuePair>();
paras.add(new BasicNameValuePair("theCityCode", name));
paras.add(new BasicNameValuePair("theUserID", ""));
String result = null;
try {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paras,
HTTP.UTF_8);
request.setEntity(entity);
HttpResponse response = new DefaultHttpClient().execute(request);
if (response.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return result;
}
最后将获得的城市在listView中显示出来,通过点击需要查看的省份(只有直辖市有天气信息)来调用
getWeather()获得,并通过Bundle将信息传入另一个WeatherMessage这个activity,下面是整个完整的City类。显示的效果如图
/**
*
*/
package com.learn.wheather;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.MarshalBase64;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.test.R;
/**
* @author liguiwu
*
*/
public class City extends Activity {
private ListView cityList;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.weather);
cityList = (ListView) findViewById(R.id.city);
// soap命名空间
String Namespace = "http://WebXml.com.cn/";
// 调用的方法
String method = "getRegionProvince";
// 请求的url
String url = "http://webService.webxml.com.cn/WebServices/WeatherWS.asmx";
// 实例化soapObject
SoapObject request = new SoapObject(Namespace, method);
// 获得序列的envelop
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
// 注册envelop
envelope.bodyOut = request;
(new MarshalBase64()).register(envelope);
// android传输对象
AndroidHttpTransport http = new AndroidHttpTransport(url);
http.debug = true;
try {
http.call("http://WebXml.com.cn/getRegionProvince", envelope);
if (envelope.getResponse() != null) {
String str = envelope.bodyIn.toString();
// 记录第一个String的位置
int start = str.indexOf("string");
// 记录最后一个;的位置
int end = str.lastIndexOf(";");
// 取start和end-3之间的字符串
String temp = str.substring(start, end - 3);
// 以;为分隔符划分数组
String[] test = temp.split(";");
List<String> city = new ArrayList<String>();
for (int i = 0; i < test.length; i++) {
if (i == 0) {
temp = test[i].substring(7);
} else {
temp = test[i].substring(8);
}
int index = temp.indexOf(",");
city.add(temp.substring(0, index));
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, city);
cityList.setAdapter(adapter);
}
cityList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
String name = cityList.getItemAtPosition(arg2).toString();
Bundle bundle = new Bundle();
bundle.putString("message", getWeather(name));
Intent intent = new Intent();
intent.setClass(City.this, WeatherMessage.class);
intent.putExtras(bundle);
startActivity(intent);
}
});
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
// 使用Apache Http来获得天气信息
public String getWeather(String name) {
String url = "http://webService.webxml.com.cn/WebServices/WeatherWS.asmx/getWeather";
HttpPost request = new HttpPost(url);
List<NameValuePair> paras = new ArrayList<NameValuePair>();
paras.add(new BasicNameValuePair("theCityCode", name));
paras.add(new BasicNameValuePair("theUserID", ""));
String result = null;
try {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paras,
HTTP.UTF_8);
request.setEntity(entity);
HttpResponse response = new DefaultHttpClient().execute(request);
if (response.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return result;
}
}
![](https://img-my.csdn.net/uploads/201207/31/1343666005_4858.png)
在WeatherMessage这个activity中解析刚才City类中传过来的天气的信息并显示,布局文件是一个TextView。解析后的信息如图
/**
*
*/
package com.learn.wheather;
import com.test.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
/**
* @author liguiwu
*
*/
public class WeatherMessage extends Activity {
private TextView message;
private String weather;
private Bundle bundle;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.weathermessage);
bundle=this.getIntent().getExtras();
weather=bundle.getString("message");
message=(TextView) findViewById(R.id.message);
message.setText(getInformation(weather));
}
//解析返回的天气预报
public String getInformation(String message){
int start=message.indexOf("<string>");
int end=message.lastIndexOf("</string>");
String temp=message.substring(start, end);
String[] test=temp.split("</string>");
String newMessage=" ";
for(int i=0;i<test.length;i++){
if(i==0){
newMessage+=test[i].substring(8);
}
else{
newMessage+=test[i].substring(12);
}
}
return newMessage;
}
}
![](https://img-my.csdn.net/uploads/201207/31/1343666142_4631.png)