Android調用WebService(天氣預報)

來源:互聯網
上載者:User
文章目錄
  • Feedback

下面例子改自網上例子: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 才正確下載對應檔案的。

選擇我們的項目,右鍵菜單中 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 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. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);okButton = (Button) this.findViewById(R.id.btn_Search);okButton.setOnClickListener(new Button.OnClickListener() {@Overridepublic 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

以下為反應的問題:

Feedback#1樓 回複 引用 查看   

2011-06-12 00:38 by
餘川川      我按照你這個步驟做下去了,怎麼不對啊???好像是我的架包錯誤,我不知道為什麼#2樓 回複 引用 查看   

2011-07-24 15:14 by
楓靜      我就按照你寫的這個代碼啟動並執行出現了07-24 07:00:55.589: ERROR/dalvikvm(315): Could not find method org.ksoap2.serialization.SoapObject.getProperty, referenced from method bzu.webclinet.WebClinetActivity.parseWeather
07-24 07:00:55.599: ERROR/AndroidRuntime(315): Uncaught handler: thread main exiting due to uncaught exception
07-24 07:00:55.619: ERROR/AndroidRuntime(315): java.lang.VerifyError: bzu.webclinet.WebClinetActivity
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at java.lang.Class.newInstanceImpl(Native Method)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at java.lang.Class.newInstance(Class.java:1472)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at android.app.Instrumentation.newActivity(Instrumentation.java:1097)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2316)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at android.app.ActivityThread.access$2100(ActivityThread.java:116)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at android.os.Handler.dispatchMessage(Handler.java:99)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at android.os.Looper.loop(Looper.java:123)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at android.app.ActivityThread.main(ActivityThread.java:4203)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at java.lang.reflect.Method.invokeNative(Native Method)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at java.lang.reflect.Method.invoke(Method.java:521)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
07-24 07:00:55.619: ERROR/AndroidRuntime(315): at dalvik.system.NativeStart.main(Native Method)
怎麼解決??#3樓 回複 引用 查看   

2011-12-07 11:49 by
leito      博主好 按照您的教程我做了一個 代碼調試顯示沒問題了 在模擬器上類比時 單擊按鈕沒有反應啊! 想問一下 那個main.xml檔案裡面都有哪些控制項~~#4樓 回複 引用 查看   

2011-12-07 13:16 by
leito      知道了 原因在於第七步 沒有添加存取權限~我把原始碼整理了一下本例原始碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.