Android通过调用Webservice实现手机号码归属地查询
此app的实现功能如图所示:
注:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx是本文webservice的提供商
具体的用法见:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?op=getMobileCodeInfo
以下是 SOAP 1.2 请求和响应示例。所显示的占位符需替换为实际值。
POST /WebServices/MobileCodeWS.asmx HTTP/1.1Host: webservice.webxml.com.cnContent-Type: application/soap+xml; charset=utf-8Content-Length: length<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <getMobileCodeInfo xmlns="http://WebXml.com.cn/"> <mobileCode>string</mobileCode> <userID>string</userID> </getMobileCodeInfo> </soap12:Body></soap12:Envelope>
HTTP/1.1 200 OKContent-Type: application/soap+xml; charset=utf-8Content-Length: length<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"> <getMobileCodeInfoResult>string</getMobileCodeInfoResult> </getMobileCodeInfoResponse> </soap12:Body></soap12:Envelope>
创建android工程MobileAddressQuery,并设置网络访问权限。
string.xml
<?xml version="1.0" encoding="utf-8"?><resources> <string name="hello">Hello World, MainActivity!</string> <string name="app_name">手机号码归属地查询</string> <string name="mobile">手机号码</string> <string name="button">归属地查询</string> <string name="error">查询失败</string></resources>
布局 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="@string/mobile" /><EditText android:layout_width="fill_parent"android:layout_height="wrap_content" android:id="@+id/mobile" /><Button android:layout_width="fill_parent"android:layout_height="wrap_content" android:text="@string/button"android:onClick="query" /><!-- 指定button的响应方法为query --><TextView android:layout_width="fill_parent"android:layout_height="wrap_content" android:id="@+id/textView" /></LinearLayout>
在src目录下创建sop12.xml,并将网址文档中提供的代码复制其中,如下
<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <getMobileCodeInfo xmlns="http://WebXml.com.cn/"> <!-- $mobile只是展示如此,在程序调用此xml文件后会将用户输入的手机号码代替 --> <mobileCode>$mobile</mobileCode> <userID></userID> </getMobileCodeInfo> </soap12:Body></soap12:Envelope>业务类:AddressService
注意访问目标地址是:
http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx
可以有协议中得到。
package cn.roco.address.service;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import org.xmlpull.v1.XmlPullParser;import android.util.Xml;import cn.roco.utils.StreamTools;public class AddressService {/** * 用于获取手机号归属地 调用webservice * @param mobile 手机号 * @return * @throws Exception */public static String getAddress(String mobile) throws Exception {String soap = readSoap();/** * 正则表达式$为特殊正则中的特殊符号须转义,即\$mobile * 而\为字符串中的特殊符号,所以用两个反斜杠,即"\\{1}quot; */soap = soap.replaceAll("\\$mobile", mobile); //将用户输入的手机号码代替sop12.xml中的$mobilebyte[] entity = soap.getBytes();String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"; //webservice提供源HttpURLConnection connection = (HttpURLConnection) new URL(path).openConnection();connection.setConnectTimeout(5000);connection.setRequestMethod("POST");connection.setRequestProperty("Content-Type","application/soap+xml; charset=utf-8");connection.setRequestProperty("Content-Length",String.valueOf(entity.length));connection.setDoOutput(true);connection.getOutputStream().write(entity);if (connection.getResponseCode() == 200) {return parseSOAP(connection.getInputStream());}return null;}/** * 解析webservice返回的数据 * <?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"> <getMobileCodeInfoResult>string</getMobileCodeInfoResult> </getMobileCodeInfoResponse> </soap12:Body></soap12:Envelope> * @param inputStream * @return * @throws Exception */private static String parseSOAP(InputStream xml) throws Exception {XmlPullParser pullParser=Xml.newPullParser();pullParser.setInput(xml,"UTF-8");int event=pullParser.getEventType();while(event!=XmlPullParser.END_DOCUMENT){switch (event) {case XmlPullParser.START_TAG:if ("getMobileCodeInfoResult".equals(pullParser.getName())) {return pullParser.nextText();}break;}event=pullParser.next();}return null;}/** * 读取sop12.xml的内容 * @return * @throws Exception */private static String readSoap() throws Exception {InputStream inputStream = AddressService.class.getClassLoader().getResourceAsStream("sop12.xml");byte[] data = StreamTools.read(inputStream);return new String(data);}}
工具类StreamTool
package cn.roco.utils;import java.io.ByteArrayOutputStream;import java.io.InputStream;public class StreamTools {/** * 读取输入流中的数据 * @param inputStream 输入流 * @return 二进制的流数据 * @throws Exception */public static byte[] read(InputStream inputStream) throws Exception {ByteArrayOutputStream outputStream=new ByteArrayOutputStream();byte[] buffer=new byte[1024];int length=0;while((length=inputStream.read(buffer))!=-1){outputStream.write(buffer,0,length);}inputStream.close();return outputStream.toByteArray();}}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="cn.roco.address" android:versionCode="1" android:versionName="1.0"><uses-sdk android:minSdkVersion="8" /> <!-- 访问Internet权限 --><uses-permission android:name="android.permission.INTERNET"/><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><uses-library android:name="android.test.runner" /></application><instrumentation android:targetPackage="cn.roco.address"android:name="android.test.InstrumentationTestRunner" /></manifest>
package cn.roco.address;import cn.roco.address.service.AddressService;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {private EditText mobileText;private TextView textView;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mobileText = (EditText) this.findViewById(R.id.mobile);textView = (TextView) this.findViewById(R.id.textView);}public void query(View v) {String mobile=mobileText.getText().toString();try {String address=AddressService.getAddress(mobile);textView.setText(address);} catch (Exception e) {e.printStackTrace();Toast.makeText(getApplicationContext(), R.string.error, 1).show();}}}