調用Web Service實現天氣預報

來源:互聯網
上載者:User

一、概念:Web Service用於消除不同平台、不同語言之間的實現差異,將現有的應用程式發布成開放式服務,從而允許互連網上任何地方、任何平台、任何語言的應用程式來訪問該服務。對於Web Service的使用者而言,不管使用何種操作平台、何種程式設計語言,只要許可權允許,都可以調用Web Service,至於Web Service底層是使用什麼樣的技術實現的對使用者是完全透明的。

二、Web Service特徵:

1、自包含性:Web Service是自包含的,Web Service使用者無須安裝任何附加軟體,只要一種支援Web和XML的程式設計語言即可;Web Service服務提供者則只需要Web伺服器和SOAP伺服器。

2、自描述性:Web Service是自描述的,用戶端和伺服器都無須關心除請求和響應訊息的內容和格式之外的任何內容,訊息格式與訊息內容一起傳播,無須外部程式輔助。

2、封裝性:Web Service是一種部署在Web應用上的對象,具備良好的封裝性。對使用者而言,僅能看到服務描述,而該服務的具體實現、運行平台都是透明的,調用者無須關心,也無法關心。Web Service作為整體提供服務。

3、可程式化性:Web Service並不提供圖形化使用者介面,而是提供編程訪問的API,Web Service調用者只需知道Web伺服器的API介面,即可使用任何平台上的、任何程式設計語言來調用Web Service。

4、鬆散耦合:當Web Service的實現發生改變時,調用者無法感受到這種變化。對調用者而言,只要服務實現的介面沒有變化,具體實現的改變是完全透明的。

5、高度的平台性:Web Service可以與其他的Web Service進行互動,具有語言和平台無關性,支援CORBA,EJB,DCOM等多種組件標準,支援各種通訊協定如:HTTP,SMTP,FTP和RMI等。

6、使用標準協議:Web Service所有的公用協議都使用標準協議描述、傳輸和交換,這些標準協議在各種平台上完全相同。使用Web Service完全可以在不同供應商之間實現互操作。

7、高度的整合能力:由於Web Service採用簡單的、易理解的標準Web協議作為通訊協定,完全屏蔽了不同平台的差異,無論CORBA,EJB還是DCOM,都可以通過這種標準的協議進行互操作,實現系統的最高可整合性。

三、優勢:

Web Service與其他網路整合技術相比,其優勢在於:

1、Web Service使用SOAP作為基本的通訊協定,更加簡單、易用。

2、Web Service採用已經廣泛使用的技術和協議,如XML、HTTP等,因此Web Service更容易掌握。

四、執行個體:

註:需要引入ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar

下面通過調用http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx網站的提供的Web
Service來實現天氣預報功能,代碼如下:

Activity:

package com.home.activity;import java.util.ArrayList;import java.util.List;import org.ksoap2.serialization.SoapObject;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemSelectedListener;import android.widget.ArrayAdapter;import android.widget.Spinner;import android.widget.TextView;import android.widget.Toast;import com.home.util.WebServiceUtil;import com.home.weatherforecast.R;public class MyWeatherActivity extends Activity {// 顯示省份的列表private Spinner provinceSpinner;// 顯示城市的列表private Spinner citySpinner;private TextView todayWeatherText;private TextView tomorrowWeatherText;private TextView afterdayWeatherText;private TextView currentWeatherText;private Handler handler;// 省份集合private List<String> provinces = new ArrayList<String>();// 城市集合private List<String> cities = new ArrayList<String>();private SoapObject detail;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);init();handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == 1) {if (provinces != null) {ArrayAdapter adapter = new ArrayAdapter(MyWeatherActivity.this,android.R.layout.simple_dropdown_item_1line,provinces);// 使用Spinner顯示省份列表provinceSpinner.setAdapter(adapter);} else {Toast.makeText(MyWeatherActivity.this, "網路異常",Toast.LENGTH_SHORT).show();}}if (msg.what == 2) {if (cities != null) {ArrayAdapter cityAdapter = new ArrayAdapter(MyWeatherActivity.this,android.R.layout.simple_dropdown_item_1line,cities);// 使用Spinner 顯示城市列表citySpinner.setAdapter(cityAdapter);} else {Toast.makeText(MyWeatherActivity.this, "網路異常",Toast.LENGTH_SHORT).show();}}if (msg.what == 3) {String todayWeather = null;String tomorrowWeather = null;String afterdayWeather = null;String currentWeather = null;// 擷取天氣實況currentWeather = detail.getProperty(4).toString();int index = currentWeather.indexOf(":");// 從實況天氣中截取出提示資訊String prompt = currentWeather.substring(0, index + 1);// 從實況天氣中截取出天氣內容String content = currentWeather.substring(index + 1);String newCurrentWeather = prompt + "\n" + content;// 解析今天的天氣情況String date = detail.getProperty(7).toString();todayWeather = "今天:" + date.split(" ")[0];todayWeather = todayWeather + "\n天氣:" + date.split(" ")[1];todayWeather = todayWeather + "\n氣溫:"+ detail.getProperty(8).toString();todayWeather = todayWeather + "\n風力:"+ detail.getProperty(9).toString() + "\n";// 解析明天的天氣情況date = detail.getProperty(12).toString();tomorrowWeather = "明天:" + date.split(" ")[0];tomorrowWeather = tomorrowWeather + "\n天氣:"+ date.split(" ")[1];tomorrowWeather = tomorrowWeather + "\n氣溫:"+ detail.getProperty(13).toString();tomorrowWeather = tomorrowWeather + "\n風力:"+ detail.getProperty(14).toString() + "\n";// 解析後天的天氣情況date = detail.getProperty(17).toString();afterdayWeather = "後天:" + date.split(" ")[0];afterdayWeather = afterdayWeather + "\n天氣:"+ date.split(" ")[1];afterdayWeather = afterdayWeather + "\n氣溫:"+ detail.getProperty(18).toString();afterdayWeather = afterdayWeather + "\n風力:"+ detail.getProperty(19).toString() + "\n";// 更新當天的天氣實況currentWeatherText.setText(newCurrentWeather);// 更新今天天氣todayWeatherText.setText(todayWeather);// 更新明天天氣tomorrowWeatherText.setText(tomorrowWeather);// 更新後天天氣afterdayWeatherText.setText(afterdayWeather);}}};new Thread() {public void run() {// 調用遠程WebService擷取省份列表provinces = WebServiceUtil.getProvinceList();Message msg = new Message();msg.what = 1;handler.sendMessage(msg);}}.start();// 當省份Spinner的選擇項改變時provinceSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {new Thread() {public void run() {// 調用遠程WebService根據省份擷取城市列表cities = WebServiceUtil.getCityListByProvince(provinceSpinner.getSelectedItem().toString());Message msg = new Message();msg.what = 2;handler.sendMessage(msg);}}.start();}@Overridepublic void onNothingSelected(AdapterView<?> arg0) {}});// 當城市Spinner的選擇項被改變時citySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {// 根據城市擷取天氣資訊showWeather(citySpinner.getSelectedItem().toString());}@Overridepublic void onNothingSelected(AdapterView<?> arg0) {}});}/** * 擷取介面組件 */private void init() {todayWeatherText = (TextView) findViewById(R.id.main_tv_weather_today);tomorrowWeatherText = (TextView) findViewById(R.id.main_tv_weather_tomorrow);afterdayWeatherText = (TextView) findViewById(R.id.main_tv_weather_afterday);currentWeatherText = (TextView) findViewById(R.id.main_tv_weather_current);provinceSpinner = (Spinner) findViewById(R.id.main_sp_province);citySpinner = (Spinner) findViewById(R.id.main_sp_city);}/** * 根據城市擷取天氣資訊 *  * @param city *            城市 */private void showWeather(final String city) {new Thread() {public void run() {// 擷取遠程WebService返回的對象detail = WebServiceUtil.getWeatherByCity(city);Message msg = new Message();msg.what = 3;handler.sendMessage(msg);}}.start();}}

訪問WebService的工具類(WebServiceUtil):

package com.home.util;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;public class WebServiceUtil {// 定義WebService的命名空間static final String SERVICE_NS = "http://WebXml.com.cn/";// 定義WebService提供服務的URLstatic final String SERVICE_URL = "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx";/** * 調用遠程WebService擷取省份列表 *  * @return List 省份列表 */public static List<String> getProvinceList() {// 調用的方法String methodName = "getRegionProvince";// 建立HttpTransportSE傳輸對象HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);ht.debug = true;// 使用SOAP1.1協議建立Envelope對象SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);// 執行個體化SoapObject對象SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);// 將SoapObject對象設定為SoapSerializationEnvelope對象的傳出SOAP訊息envelope.bodyOut = soapObject;// 設定與.NET提供的WebService保持較好的相容性envelope.dotNet = true;try {// 調用WebServiceht.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 (Exception e) {e.printStackTrace();}return null;}/** * 根據省份擷取城市列表 *  * @param province * @return List 城市列表 */public static List<String> getCityListByProvince(String province) {// 調用的方法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協議建立Envelope對象SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);envelope.bodyOut = soapObject;// 設定與.NET提供的WebService保持較好的相容性envelope.dotNet = true;try {// 調用WebServiceht.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 (Exception e) {e.printStackTrace();}return null;}/** * 解析伺服器響應的SOAP訊息 *  * @param detail *            SOAP訊息 * @return List */private static List<String> parseProvinceOrCity(SoapObject detail) {ArrayList<String> result = new ArrayList<String>();for (int i = 0; i < detail.getPropertyCount(); i++) {// 解析出每個省份result.add(detail.getProperty(i).toString().split(",")[0]);}return result;}/** * 根據城市擷取天氣狀況 *  * @param cityName *            城市名稱 * @return SoapObject */public static SoapObject getWeatherByCity(String cityName) {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提供的WebService保持較好的相容性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) {}return null;}}

布局XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content" >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="請選擇省份:"            android:textSize="20dp" />        <!-- 讓使用者選擇省份的Spinner -->        <Spinner            android:id="@+id/main_sp_province"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content" >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="請選擇城市:"            android:textSize="20dp" />        <!-- 讓使用者選擇城市的Spinner -->        <Spinner            android:id="@+id/main_sp_city"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout>    <!-- 顯示今天天氣的文字框 -->    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content" >        <TextView            android:id="@+id/main_tv_weather_today"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout>    <!-- 顯示明天天氣的文字框 -->    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content" >        <TextView            android:id="@+id/main_tv_weather_tomorrow"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout>    <!-- 顯示後天天氣的文字框 -->    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content" >        <TextView            android:id="@+id/main_tv_weather_afterday"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout>    <!-- 顯示當前天氣的文字框 -->    <TextView        android:id="@+id/main_tv_weather_current"        android:layout_width="match_parent"        android:layout_height="wrap_content" /></LinearLayout>

附片效果:

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.