`

Android平台调用WebService详解

 
阅读更多

本文将通过一个简单的示例讲解和演示Android平台的Web Service开发。

Ksoap2-android简介
      在Android平台调用Web Service需要依赖于第三方类库ksoap2,它是一个SOAP Web service客户端开发包,主要用于资源受限制的Java环境如Applets或J2ME应用程序(CLDC/ CDC/MIDP)。认真读完对ksoap2的介绍你会发现并没有提及它应用于Android平台开发,没错,在Android平台中我们并不会直接使用ksoap2,而是使用ksoap2 android。KSoap2 Android 是Android平台上一个高效、轻量级的SOAP开发包,等同于Android平台上的KSoap2的移植版本。

Ksoap2-android jar包下载
      ksoap2 android当前的最新版本为2.5.4,名为ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar,它的下载地址是:http://code.google.com/p/ksoap2-android/,进入页面后,点击“Downloads”标签页,如下图所示:
     
      在“Downloads”页面的下方,找到如下图所示的紫色的链接,然后在链接上点击右键,找到相关下载项进行下载即可。右键菜单中显示的下载项依据浏览器的不同而有所区别,比如我使用的360浏览器,在键接上点击右键,然后选择“使用360安全浏览器下载”即可弹出下载保存对话框。
     

Android平台调用Web Service示例
     下面将通过一个示例讲解如何在Android平台调用Web Service。既然要调用Web Service,那就要先有Web Service。我们还是选择使用上篇文章中介绍的查询手机号码归属地的Web service,它的WSDL为http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
1)新建Android工程,引入上面下载的ksoap2-android类库
      Android工程的创建就不多说了,主要想说明的是如何向Android工程中添加第三方jar包。当然,添加第3方jar的方式有多种,我个人比较喜欢用下面这种方式,即先将第三方jar包拷贝到工程某个目录下,再将其加入到工程的Build Path中
      例如,我创建的Android工程名为WSClient,在工程名上点击右键,新建一个Folder(目录或文件夹),名为libs,然后将ksoap2-android类库拷贝到libs目录中,如下图所示:
            
      接着,在jar包ksoap2-android-assembly-2.4-jar-with-dependencies.jar上点击右键,依次选择“Build Path”-“Add to Build Path”。再在工程名上点击右键,依次选择“Build Path”-“Config Build Path...”,将看到如下所示界面:
     
选中ksoap2 jar包前面的选项框,点击OK,则完成了ksoap2 jar包的添加(说明:在Android工程中,添加其它jar包的方法完全一样,操作一两遍后,你会发现其实很简单的)。
2)编写布局文件res/layout/main.xml      

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     android:paddingTop="5dip"  
  7.     android:paddingLeft="5dip"  
  8.     android:paddingRight="5dip"  
  9.     >  
  10.     <TextView  
  11.         android:layout_width="fill_parent"   
  12.         android:layout_height="wrap_content"   
  13.         android:text="手机号码(段):"  
  14.     />  
  15.     <EditText android:id="@+id/phone_sec"  
  16.         android:layout_width="fill_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:inputType="textPhonetic"  
  19.         android:singleLine="true"  
  20.         android:hint="例如:1398547"  
  21.     />  
  22.     <Button android:id="@+id/query_btn"  
  23.         android:layout_width="wrap_content"  
  24.         android:layout_height="wrap_content"  
  25.         android:layout_gravity="right"  
  26.         android:text="查询"  
  27.     />  
  28.     <TextView android:id="@+id/result_text"  
  29.         android:layout_width="wrap_content"   
  30.         android:layout_height="wrap_content"   
  31.         android:layout_gravity="center_horizontal|center_vertical"  
  32.     />  
  33. </LinearLayout>  
<?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"
    android:paddingTop="5dip"
    android:paddingLeft="5dip"
    android:paddingRight="5dip"
    >
    <TextView
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    android:text="手机号码(段):"
    />
    <EditText android:id="@+id/phone_sec"
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
    	android:inputType="textPhonetic"
    	android:singleLine="true"
    	android:hint="例如:1398547"
    />
    <Button android:id="@+id/query_btn"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:layout_gravity="right"
    	android:text="查询"
   	/>
	<TextView android:id="@+id/result_text"
	    android:layout_width="wrap_content" 
	    android:layout_height="wrap_content" 
	    android:layout_gravity="center_horizontal|center_vertical"
    />
</LinearLayout>

3)编写MainActivity类

  1. package com.liufeng.ws.activity;  
  2.   
  3. import org.ksoap2.SoapEnvelope;  
  4. import org.ksoap2.serialization.SoapObject;  
  5. import org.ksoap2.serialization.SoapSerializationEnvelope;  
  6. import org.ksoap2.transport.HttpTransportSE;  
  7.   
  8. import android.app.Activity;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.Button;  
  13. import android.widget.EditText;  
  14. import android.widget.TextView;  
  15.   
  16. /** 
  17.  * Android平台调用WebService(手机号码归属地查询) 
  18.  *  
  19.  * @author liufeng 
  20.  * @date 2011-05-18 
  21.  */  
  22. public class MainActivity extends Activity {  
  23.     private EditText phoneSecEditText;  
  24.     private TextView resultView;  
  25.     private Button queryButton;  
  26.   
  27.     @Override  
  28.     public void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.main);  
  31.   
  32.         phoneSecEditText = (EditText) findViewById(R.id.phone_sec);  
  33.         resultView = (TextView) findViewById(R.id.result_text);  
  34.         queryButton = (Button) findViewById(R.id.query_btn);  
  35.   
  36.         queryButton.setOnClickListener(new OnClickListener() {  
  37.             @Override  
  38.             public void onClick(View v) {  
  39.                 // 手机号码(段)   
  40.                 String phoneSec = phoneSecEditText.getText().toString().trim();  
  41.                 // 简单判断用户输入的手机号码(段)是否合法   
  42.                 if ("".equals(phoneSec) || phoneSec.length() < 7) {  
  43.                     // 给出错误提示   
  44.                     phoneSecEditText.setError("您输入的手机号码(段)有误!");  
  45.                     phoneSecEditText.requestFocus();  
  46.                     // 将显示查询结果的TextView清空   
  47.                     resultView.setText("");  
  48.                     return;  
  49.                 }  
  50.                 // 查询手机号码(段)信息   
  51.                 getRemoteInfo(phoneSec);  
  52.             }  
  53.         });  
  54.     }  
  55.   
  56.     /** 
  57.      * 手机号段归属地查询 
  58.      *  
  59.      * @param phoneSec 手机号段 
  60.      */  
  61.     public void getRemoteInfo(String phoneSec) {  
  62.         // 命名空间   
  63.         String nameSpace = "http://WebXml.com.cn/";  
  64.         // 调用的方法名称   
  65.         String methodName = "getMobileCodeInfo";  
  66.         // EndPoint   
  67.         String endPoint = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";  
  68.         // SOAP Action   
  69.         String soapAction = "http://WebXml.com.cn/getMobileCodeInfo";  
  70.   
  71.         // 指定WebService的命名空间和调用的方法名   
  72.         SoapObject rpc = new SoapObject(nameSpace, methodName);  
  73.   
  74.         // 设置需调用WebService接口需要传入的两个参数mobileCode、userId   
  75.         rpc.addProperty("mobileCode", phoneSec);  
  76.         rpc.addProperty("userId""");  
  77.   
  78.         // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本   
  79.         SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);  
  80.   
  81.         envelope.bodyOut = rpc;  
  82.         // 设置是否调用的是dotNet开发的WebService   
  83.         envelope.dotNet = true;  
  84.         // 等价于envelope.bodyOut = rpc;   
  85.         envelope.setOutputSoapObject(rpc);  
  86.   
  87.         HttpTransportSE transport = new HttpTransportSE(endPoint);  
  88.         try {  
  89.             // 调用WebService   
  90.             transport.call(soapAction, envelope);  
  91.         } catch (Exception e) {  
  92.             e.printStackTrace();  
  93.         }  
  94.   
  95.         // 获取返回的数据   
  96.         SoapObject object = (SoapObject) envelope.bodyIn;  
  97.         // 获取返回的结果   
  98.         String result = object.getProperty(0).toString();  
  99.   
  100.         // 将WebService返回的结果显示在TextView中   
  101.         resultView.setText(result);  
  102.     }  
  103. }  
package com.liufeng.ws.activity;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
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.TextView;

/**
 * Android平台调用WebService(手机号码归属地查询)
 * 
 * @author liufeng
 * @date 2011-05-18
 */
public class MainActivity extends Activity {
	private EditText phoneSecEditText;
	private TextView resultView;
	private Button queryButton;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		phoneSecEditText = (EditText) findViewById(R.id.phone_sec);
		resultView = (TextView) findViewById(R.id.result_text);
		queryButton = (Button) findViewById(R.id.query_btn);

		queryButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 手机号码(段)
				String phoneSec = phoneSecEditText.getText().toString().trim();
				// 简单判断用户输入的手机号码(段)是否合法
				if ("".equals(phoneSec) || phoneSec.length() < 7) {
					// 给出错误提示
					phoneSecEditText.setError("您输入的手机号码(段)有误!");
					phoneSecEditText.requestFocus();
					// 将显示查询结果的TextView清空
					resultView.setText("");
					return;
				}
				// 查询手机号码(段)信息
				getRemoteInfo(phoneSec);
			}
		});
	}

	/**
	 * 手机号段归属地查询
	 * 
	 * @param phoneSec 手机号段
	 */
	public void getRemoteInfo(String phoneSec) {
		// 命名空间
		String nameSpace = "http://WebXml.com.cn/";
		// 调用的方法名称
		String methodName = "getMobileCodeInfo";
		// EndPoint
		String endPoint = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx";
		// SOAP Action
		String soapAction = "http://WebXml.com.cn/getMobileCodeInfo";

		// 指定WebService的命名空间和调用的方法名
		SoapObject rpc = new SoapObject(nameSpace, methodName);

		// 设置需调用WebService接口需要传入的两个参数mobileCode、userId
		rpc.addProperty("mobileCode", phoneSec);
		rpc.addProperty("userId", "");

		// 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);

		envelope.bodyOut = rpc;
		// 设置是否调用的是dotNet开发的WebService
		envelope.dotNet = true;
		// 等价于envelope.bodyOut = rpc;
		envelope.setOutputSoapObject(rpc);

		HttpTransportSE transport = new HttpTransportSE(endPoint);
		try {
			// 调用WebService
			transport.call(soapAction, envelope);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 获取返回的数据
		SoapObject object = (SoapObject) envelope.bodyIn;
		// 获取返回的结果
		String result = object.getProperty(0).toString();

		// 将WebService返回的结果显示在TextView中
		resultView.setText(result);
	}
}

讲解:
      注意点1:如代码中的62-69行所示,调用Web Service之前你需要先弄清楚这4个的值分别是什么:命名空间、调用的方法名称、EndPoint和SOAP Action。当在浏览器中访问WSDL时,很容易得知命名空间、调用的方法名称是什么(不明白的请看上篇文章),至于EndPoint通常是将WSDL地址末尾的"?wsdl"去除后剩余的部分;而SOAP Action通常为命名空间 + 调用的方法名称。
      注意点2:75-76行是设置调用WebService接口方法需要传入的参数。(在WSDL中能够看到调用方法需要传入的参数个数及参数名称,在设置参数时最好指明每一个传入参数的名称,如本例中的mobileCode、userId。网上有些资料说在需要传入多个参数时,只要多个参数的顺序与WSDL中参数出现的顺序一致即可,名称并不需要和WSDL中的一致,但实际测试发现,大多数情况下并不可行!
      例如下面图版上显示的WSDL片段,调用该Web Service的checkUserInfo方法就需要传入4个参数,参数名称分别为:in0、in1、in2和in3。
           

      注意点3也许你会对第100行代码产生疑惑,为什么要用object.getProperty("getMobileCodeInfoResult")来取得调用结果?那是因为WSDL中明确告诉了返回结果是String数组,它的名称为getDatabaseInfoResult,WSDL中的描述如下:
           <s:elementminOccurs="0" maxOccurs="1" name="getDatabaseInfoResult" type="tns:ArrayOfString" /> 
     
本例中调用WebService后返回的结果如下所示:
           <?xml version="1.0" encoding="utf-8"?> 
            
<string xmlns="http://WebXml.com.cn/">1398547:贵州 贵阳 贵州移动黔中游卡</string>
咦,这里明明返回的是xml格式的内容,为什么我们不需要通过解析xml来获取我们需要的内容呢?其实如果你仔细看代码中的96-97行并不难发现:
            // 获取返回的数据
            SoapObject object = (SoapObject) envelope.bodyIn;

ksoap2能够将返回的xml转换成SoapObject对象,然后我们就可以通过操作对象的方式来获取需要的数据了。
      注意点4同样还是第100行代码。从有些WSDL中我们并不能得知返回结果的名称(如本例中的getMobileCodeInfoResult),那又该如何调用呢?其实上面已经暗示了这个问题:当通过第97行代码获取返回结果并将其转换成SoapObject对象后,如果你并不知道通过该对象的哪个属性来取值,你完全可以调用对象的toString()方法来查看返回的内容,例如将本例中的第100行代码替换成:
            // 获取返回的结果
             String result = object.toString();

这样得到的返回结果为:
     
注意看括号{}里面的内容是一个键-值对形式,以等号=分隔,我们正是通过=号左边的“getMobileCodeInfoResult”来获取右边的查询结果。
      其实在不知道返回结果名称时(如本例的100行,我们并不知道返回结果中有属性getMobileCodeInfoResult),有一种更为简便的方法,直接通过索引下标来获取属性值,也就是将第100行代码替换为:
            String result = object.getProperty(0).toString();
      注意点5:本例中只返回了一个值,但有些WebService会返回多个值该怎么获取?获取方法与本例完全一样,只是需要注意的是如果是返回多个值,通过第100代码object.getProperty(0);得到的可能仍然是一个SoapObject。不断地调用getProperty()方法;总能得到你想要的全部结果。
      注意点6:在调用某些WebService时,可能会报一些异常,但你又发现除了调用的WebService不同之外,其它地方的写法和我的完全一样,这又该如何解决呢?尝试改变第79代码中SOAP的版本号,可以分别尝试使用SoapEnvelope.VER10、SoapEnvelope.VER11、SoapEnvelope.VER12这样三个值。另外,在调用某些WebService时,可能在第91行代码中,调用WebService时并不需要传入soapAction,将其置为null即可。
4)在AndroidManifest.xml中配置添加访问网络的权限(千万别忘记!!!)      

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.liufeng.ws.activity"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  7.         <activity android:name=".MainActivity" android:label="@string/app_name">  
  8.             <intent-filter>  
  9.                 <action android:name="android.intent.action.MAIN" />  
  10.                 <category android:name="android.intent.category.LAUNCHER" />  
  11.             </intent-filter>  
  12.         </activity>  
  13.     </application>  
  14.   
  15.     <uses-sdk android:minSdkVersion="4" />  
  16.     <!-- 访问网络的权限 -->  
  17.     <uses-permission android:name="android.permission.INTERNET" />   
  18. </manifest>   
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.liufeng.ws.activity"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity" 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-sdk android:minSdkVersion="4" />
    <!-- 访问网络的权限 -->
	<uses-permission android:name="android.permission.INTERNET" /> 
</manifest> 

5)运行结果
     

 

转自:http://blog.csdn.net/lyq8479/article/details/6428288

分享到:
评论

相关推荐

    Android平台调用WebService详解 (实例代码更改)

    本文将详细介绍如何在Android中调用Web Service,并提供一个实例代码的更改,以便进行异步处理,提高应用性能。 首先,我们需要理解Web Service的概念。Web Service是一种基于网络的、能够被其他应用程序(如...

    Android之Webservice详解与调用天气预报Webservice完整实例

    综上所述,这个实例涵盖了Android调用Web Service的基本流程,从理解Web Service的概念,到选择合适的库(如Ksoap2),再到构建请求、解析响应、处理异常以及UI显示。通过这个实例,开发者可以掌握在Android平台上...

    Android调用WebService详解例程

    本例程是android端如何去调用...android SDK没有直接调用webservice的库,最常用的是借助ksoap2-android这个第三方SDK。 该Demo参考《疯狂Android讲义》并做改动,希望可以帮助到初次接触Androi调用WebService的朋友

    android 调用.net webservice

    ### Android调用.NET WebService详解 #### 一、概述 在Android开发中,与服务器进行交互是必不可少的一个环节。常见的交互方式包括HTTP请求、RESTful API等,而WebService作为一种传统但依然广泛使用的通信协议,...

    Android_WebView实例详解

    Android WebView 实例详解 Android WebView 是 Android 平台中一种特殊的组件,可以在应用程序中显示 web 页面。它基于 WebKit 内核浏览器,提供了一个可以在 Android 应用程序中嵌入网页浏览器的解决方案。 一、...

    《android核心技术与实例详解》源码(完整版)

    《Android核心技术与实例详解》是Android开发者们常常参考的一本技术书籍,其源码的完整版为学习者提供了深入理解Android开发的宝贵资源。这本书涵盖了Android应用开发的多个重要方面,包括但不限于UI设计、数据存储...

    Android开发教程之调用摄像头功能的方法详解

    本文实例讲述了Android调用摄像头功能的方法。分享给大家供大家参考,具体如下: 我们要调用摄像头的拍照功能,显然 第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在SD卡中,必须加入SD卡读写权限...

    Android NDK入门 实例 详解

    Android NDK(Native Development Kit)是Google为Android平台提供的一个工具集,允许开发者使用C/C++等原生代码编写部分应用程序,从而实现高性能计算、图形处理或者利用已有的C/C++库。本教程将深入浅出地介绍...

    《Android创意实例详解》源代码

    《Android创意实例详解》源代码是一份非常宝贵的资源,它为Android开发者提供了丰富的实践案例,帮助读者深入理解和应用Android开发技术。这份源代码涵盖了多个关键的Android开发知识点,包括但不限于用户界面设计、...

    axis2搭建webService并包含android调用此WebService服务案例

    ### Android调用eclipse+axis2搭建的webService服务详解 #### Eclipse+axis2+Tomcat搭建webService服务 **准备工作** 在开始之前,确保你有以下工具: 1. **Eclipse**: 用于开发Java项目和webService。可以从...

    Android与JS之间跨平台异步调用实例详解

    本篇文章将详细解析如何在 Android 和 JS 之间实现跨平台的异步调用。 首先,让我们了解一下为什么需要这种跨平台调用。在某些情况下,比如开发基于 WebView 的应用时,可能需要通过 JavaScript 进行界面展示,而...

    android intent 应用实例详解

    总之,Intent 是 Android 平台上组件间通信的关键,通过显式和隐式 Intent,开发者可以灵活地启动活动、传递数据并实现应用程序间的交互。理解 Intent 的工作原理和使用方法对于构建功能丰富的 Android 应用至关重要...

    Android百度地图实例详解之仿摩拜单车APP.zip

    综上所述,"Android百度地图实例详解之仿摩拜单车APP"是一个全面的示例,涵盖了Android地图开发的许多重要技术,对于学习和实践移动应用开发,尤其是地理位置相关的功能,具有很高的参考价值。通过阅读和理解源代码...

    Android亮屏和熄屏控制实例详解

    本文实例讲述了Android亮屏和熄屏控制实现方法。分享给大家供大家参考,具体如下: 一、概述 我们的Android应用程序很多需要和亮屏和熄屏打交道,比如闹钟的时候,需要保持亮屏,之后又需要熄屏。那么今天,我们来...

    Android 调用WCF实例详解

    总之,Android调用WCF服务涉及服务端的创建和配置,以及客户端的HTTP请求实现。理解WCF服务的工作原理和Android网络请求机制是实现这一目标的关键。遵循以上步骤,开发者可以构建一个简单的Android应用,有效地与WCF...

    Android核心技术与实例详解

    ### Android核心技术与实例详解 #### 一、Android概述 Android是一种基于Linux内核(主要版本为2.6)的操作系统,由Google公司和开放手机联盟(Open Handset Alliance,OHA)领导及开发,主要用于移动设备。...

    Android数据库SQLite详解

    在Android开发中,SQLite是一个非常重要的组成部分,它是一个轻量级的、开源的、嵌入式的SQL数据库引擎,被广泛用于存储和管理应用程序中的数据。SQLite具有高效、可靠且易于集成的特点,使得它成为Android应用数据...

    Android NDK开发(1)----- Java与C互相调用实例详解

    在实际应用中,如Android Camera的例子,C/C++代码可能由硬件事件触发,不需要Java层主动调用。当有新数据可用时,C/C++代码会通过JNI回调Java方法,这样可以实现异步通信,提高程序响应性。例如,当图像数据准备好...

Global site tag (gtag.js) - Google Analytics