一、擷取並使用KSOAP包
在Android SDK中並沒有提供調用WebService的庫,因此,需要使用第三方的SDK來調用WebService。PC版本的WebService庫非常豐 富,但這些對Android來說過於龐大。適合手機的WebService用戶端的SDK有一些,比較常用的是KSOAP2。
KSOAP2 地址:http://code.google.com/p/ksoap2-android/
選擇我們的項目,右鍵菜單中 Build Path –> Add External Archives… 增加這個下載的包
增加好後,我們在 選擇我們的項目,右鍵菜單中 Build Path –> Configure Build Path 的 Libraries 中可以看到下面圖:
二,分以下幾步來調用 WebService
1、指定 WebService 的命名空間和調用方法
import org.ksoap2.serialization.SoapObject;private static final String NAMESPACE = "http://WebXml.com.cn/";private static final String METHOD_NAME = "getWeatherbyCityName";SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME);
SoapObject類的第一個參數表示WebService的命名空間,可以從WSDL文檔中找到WebService的命名空間。
第二個參數表示要調用的WebService方法名。
2、設定調用方法的參數值,如果沒有參數,可以省略,設定方法的參數值的代碼如下:
rpc.addProperty("theCityName", "北京");
要注意的是,addProperty方法的第1個參數雖然表示調用方法的參數名,但該參數值並不一定與服務端的WebService類中的方法參數名一致,只要設定參數的順序一致即可。
3、產生調用Webservice方法的SOAP請求資訊。
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);envelope.bodyOut = rpc;envelope.dotNet = true;envelope.setOutputSoapObject(rpc);
建立SoapSerializationEnvelope對象時需要通過SoapSerializationEnvelope類的構造方法設定SOAP協議的版本號碼。
該版本號碼需要根據服務端WebService的版本號碼設定。
在建立SoapSerializationEnvelope對象後,不要忘了設定SOAPSoapSerializationEnvelope類的bodyOut屬性,
該屬性的值就是在第一步建立的SoapObject對象。
4、建立HttpTransportsSE對象。
這裡不要使用 AndroidHttpTransport ht = new AndroidHttpTransport(URL); 這是一個要到期的類
private static String URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx";HttpTransportSE ht = new HttpTransportSE(URL);
ht.debug = true;
5、使用call方法調用WebService方法
private static String SOAP_ACTION = "http://WebXml.com.cn/getWeatherbyCityName";ht.call(SOAP_ACTION, envelope);
網上有人說這裡的call的第一個參數為null,但是經過我的測試,null是不行的。
第2個參數就是在第3步建立的SoapSerializationEnvelope對象。
6、獲得WebService方法的返回結果
有兩種方法:
1、使用getResponse方法獲得返回資料。
private SoapObject detail;detail =(SoapObject) envelope.getResponse();
2、使用 bodyIn 及 getProperty。
private SoapObject detail;SoapObject result = (SoapObject)envelope.bodyIn;detail = (SoapObject) result.getProperty("getWeatherbyCityNameResult");
7、 這時候執行會出錯,提示沒有許可權訪問網路
需要修改 AndroidManifest.xml 檔案,賦予相應許可權
簡單來說就是增加下面這行配置:<uses-permission android:name="android.permission.INTERNET"></uses-permission>
完整的 AndroidManifest.xml 檔案 如下:
註:Android 中在代碼中為了調試寫了system.out.print()輸出項
在菜單:Window-->show view-->other-->找到Android,選擇Logcat 是可以看到輸出的,
如果你想在一個單獨的視窗看到system.out.print()的輸出的話,可以在logcat介面點那個綠色的“+”好,
在Filter name 和 By log tag裡面均填入System.out,這樣的話你就能在單獨的介面查看system.out.print()的輸出了!!
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ghj1976.MyWeather" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MyWeatherActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"></uses-permission></manifest>
完整的代碼如下:
package com.duandian;
import java.io.UnsupportedEncodingException;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class WeatherForcastActivity extends Activity {
private static final String NAMESPACE = "http://WebXml.com.cn/";
// WebService地址
private static String URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx";
private static final String METHOD_NAME = "getWeatherbyCityName";
private static String SOAP_ACTION = "http://WebXml.com.cn/getWeatherbyCityName";
private String weatherToday;
private EditText et;
private Button okButton;
private SoapObject detail;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
okButton = (Button) findViewById(R.id.ok);
et = (EditText) findViewById(R.id.et);
// et.setOnClickListener(new OnClickListener() {
//
// @Override
// public void onClick(View v) {
// // TODO Auto-generated method stub
//
// }
// });
okButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
CharSequence edit_value = et.getText();
String city = edit_value.toString();
getWeather(city);
// showWeather();
}
});
}
// private void showWeather() {
// et = (EditText) findViewById(R.id.et);
// }
@SuppressWarnings("deprecation")
public void getWeather(String cityName) {
try {
System.out.println("rpc------");
SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME);
System.out.println("rpc" + rpc);
System.out.println("cityName is " + cityName);
rpc.addProperty("theCityName", cityName);
HttpTransportSE ht = new HttpTransportSE(URL);
// AndroidHttpTransport ht = new AndroidHttpTransport(URL);
ht.debug = true;
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.bodyOut = rpc;
envelope.dotNet = true;
envelope.setOutputSoapObject(rpc);
ht.call(SOAP_ACTION, envelope);
SoapObject result = (SoapObject) envelope.bodyIn;
detail = (SoapObject) result
.getProperty("getWeatherbyCityNameResult");
System.out.println("result" + result);
System.out.println("detail" + detail);
Toast.makeText(WeatherForcastActivity.this, detail.toString(),
Toast.LENGTH_LONG).show();
parseWeather(detail);
return;
} catch (Exception e) {
e.printStackTrace();
}
}
private void parseWeather(SoapObject detail)
throws UnsupportedEncodingException {
String date = detail.getProperty(6).toString();
weatherToday = "今天:" + date.split(" ")[0];
weatherToday = weatherToday + "\n天氣:" + date.split(" ")[1];
weatherToday = weatherToday + "\n氣溫:"
+ detail.getProperty(5).toString();
weatherToday = weatherToday + "\n風力:"
+ detail.getProperty(7).toString() + "\n";
System.out.println("weatherToday is " + weatherToday);
Toast.makeText(WeatherForcastActivity.this, weatherToday,
Toast.LENGTH_LONG).show();
}
}
main.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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="請輸入你要查詢天氣的城市"
android:textSize="30sp"
/>
<EditText
android:id="@+id/et"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:text=""
/>
<Button
android:id="@+id/ok"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Ok"
/>
</LinearLayout>