Android呼叫天氣預報的WebService簡單例子

lostinai發表於2013-04-20

轉自http://www.cnblogs.com/ghj1976/archive/2011/04/26/2028904.html

下面例子改自網上例子:http://express.ruanko.com/ruanko-express_34/technologyexchange5.html

不過網上這個例子有些沒有說明,有些情況不一樣了,所以我重新寫了。

一、獲取並使用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.4-jar-with-dependencies.jar

注意:

我在使用ksoap2-android時犯了一個低階錯誤:使用時報錯誤:The import org.ksoap2 cannot be resolved。
當時分析這個問題時一直以為是Eclipse出了問題,找了好多方法都不行,
實際是我下載的ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar檔案是錯誤的導致的,走了彎路。

http://code.google.com/p/ksoap2-android/wiki/HowToUse?tm=2 頁面 通過滑鼠右鍵連結另存為存的是同名的一個純文字的Html檔案。而不是我們想要的。

我是在
http://code.google.com/p/ksoap2-android/source/browse/m2-repo/com/google/code/ksoap2-android/ksoap2-android-assembly/2.5.4/ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar  點 View raw file 才正確下載對應檔案的。

image

 

選擇我們的專案,右鍵選單中 Build Path –> Add External Archives… 增加這個下載的包

image

增加好後,我們在 選擇我們的專案,右鍵選單中 Build Path –> Configure Build Path 的 Libraries 中可以看到下面圖:

image

二,分以下幾步來呼叫 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 ghj1976.MyWeather;

import java.io.UnsupportedEncodingException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

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

public class MyWeatherActivity extends Activity {

	private Button okButton;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		okButton = (Button) this.findViewById(R.id.btn_Search);
		okButton.setOnClickListener(new Button.OnClickListener() {
			@Override
			public void onClick(View v) {
				  String city = "北京";
				  getWeather(city);  
			}

		});
	}

	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 SoapObject detail;

	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);

			
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.bodyOut = rpc;
			envelope.dotNet = true;
			envelope.setOutputSoapObject(rpc);
			
			HttpTransportSE ht = new HttpTransportSE(URL);

			//AndroidHttpTransport ht = new AndroidHttpTransport(URL);
			ht.debug = true;

			ht.call(SOAP_ACTION, envelope);
			//ht.call(null, envelope);

			//SoapObject result = (SoapObject)envelope.bodyIn;
			//detail = (SoapObject) result.getProperty("getWeatherbyCityNameResult");

			detail =(SoapObject) envelope.getResponse();
			
			//System.out.println("result" + result);
			System.out.println("detail" + detail);
			Toast.makeText(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(this, weatherToday, Toast.LENGTH_LONG).show();

	}
}

參考資料

在Android中訪問WebService介面
http://www.cnblogs.com/yy-7years/archive/2011/01/24/1943286.html

Android呼叫WebService
http://express.ruanko.com/ruanko-express_34/technologyexchange5.html

中國氣象局的WebService地址
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx

Android與伺服器端資料互動(基於SOAP協議整合android+webservice)
http://www.cnblogs.com/zhangdongzi/archive/2011/04/19/2020688.html


相關文章