本内容适合初学Android网络编程、XML解析的童鞋查看,主要内容已添加注释,所以只贴代码即可。
效果图:
①访问网络、解析XML文件工具类: WebServiceUtil.java
package com.lee.webservicedemo2.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.content.Context;
import android.util.Log;
/**
* @author Administrator
*网络上很多使用SOAP协议的方法,这里就使用http
*/
public class WebServiceUtil {
static String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo";
/**
* 使用HttpURLConnection的get方式访问网络,获取手机号码归属地数据流
* By Lee in 2014年9月3日
* */
public static String getAddressGet(Context context, String mobileNumber)
throws IOException {
//String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo";
path = path + "?mobileCode=" + URLEncoder.encode(mobileNumber, "utf-8")
+ "&userId=";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
Log.v("Lee", "GET conn = " + conn);
if (conn.getResponseCode() == 200) {
Log.v("Lee", "Connect Successed!");
return parserXML(conn.getInputStream());
} else {
Log.v("Lee",
"Connect failed! + error code: " + conn.getResponseCode());
}
return null;
}
/**
* 使用HttpURLConnection的Post方式访问网络,获取手机号码归属地数据流
* By Lee in 2014年9月3日
* */
public static String getAddressPost(Context context, String mobileNumber)
throws IOException {
//String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo";
URL url = new URL(path);
String content = "mobileCode=" + URLEncoder.encode(mobileNumber, "utf-8")+ "&userID=";
Log.v("Lee", "POST content = " + content);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length",
content.getBytes().length + "");
conn.connect();
//one:
// conn.getOutputStream().write(content.getBytes());
// conn.getOutputStream().flush();
// conn.getOutputStream().close();
//two:
// DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
// dos.writeBytes(content);
// dos.flush();
// dos.close();
//three:
PrintWriter printer = new PrintWriter(conn.getOutputStream());
printer.print(content);
printer.flush();
printer.close();
Log.v("Lee", "POST conn = " + conn);
if (conn.getResponseCode() == 200) {
Log.v("Lee", "Connect Successed!");
return parserXML(conn.getInputStream());
} else {
Log.v("Lee",
"Connect failed! + error code: " + conn.getResponseCode());
}
return null;
}
/**
* 使用apache HttpClient的get方式访问网络,获取手机号码归属地数据流
* By Lee in 2014年9月3日
*
* 存在问题:只能查询一次,之后会出现java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)错误,
* 网上找了,没有找到解决方法,不知道是哪里的问题
* */
public static String getAddressHttpClientGet(Context context, String mobileNumber) throws Exception{
HttpClient httpClient = new DefaultHttpClient();
path = path + "?mobileCode=" + URLEncoder.encode(mobileNumber, "utf-8")
+ "&userId=";
HttpGet httpGet = new HttpGet(path);
//httpGet.setHeader("Accept", "Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
//httpGet.setHeader(name, value)
//System.setProperty("http.keepAlive", "false");
HttpResponse httpResponse = httpClient.execute(httpGet);
InputStream inputStream = httpResponse.getEntity().getContent();
//httpGet.abort();
if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//Log.v("Lee", "HttpClientGet---inputStream = " + inputStream);
String addr = parserXML(inputStream);
inputStream.close();
httpGet.abort();
return addr;
}
return null;
}
/**
* 使用apache HttpClient的Post方式访问网络,获取手机号码归属地数据流
* By Lee in 2014年9月3日
* */
public static String getAddressHttpClientPost(Context context, String mobileNumber) throws Exception{
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpRequest = new HttpPost(path);
List<NameValuePair> vars = new ArrayList<NameValuePair>();
vars.add(new BasicNameValuePair("mobileCode", mobileNumber));
vars.add(new BasicNameValuePair("userId", ""));
httpRequest.setEntity(new UrlEncodedFormEntity(vars, HTTP.UTF_8));
HttpResponse httpResponse = httpClient.execute(httpRequest);
InputStream inputStream = httpResponse.getEntity().getContent();
//httpGet.abort();
if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//Log.v("Lee", "HttpClientGet---inputStream = " + inputStream);
String addr = parserXML(inputStream);
inputStream.close();
httpRequest.abort();
return addr;
}
return null;
}
/**
* @param inputStream 传入的是XML文件流对象
* @return
*/
public static String parserXML(InputStream inputStream) {
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
try {
SAXParser parser = saxFactory.newSAXParser();
ParserXMLHandler handler = new ParserXMLHandler();
parser.parse(inputStream, handler);
return handler.getAddress();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* XML文件解析
* Android常用的xml解析方法有DOM、SAX、PULL,这里其实使用PULL方法更简易的,
* 不过为了熟悉一下SAX的解析流程,本例使用了SAX
* */
static class ParserXMLHandler extends DefaultHandler {
private String address;
private String preTag; //记住前一个节点
public String getAddress() {
return address;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
if (preTag != null) {
String content = new String(ch, start, length);
if ("string".equals(preTag)) {
address = content;
Log.v("Lee", "content == " + content);
}
}
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
preTag = null;
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
preTag = localName;
}
}
}
主界面代码MainActivity.java
package com.lee.webservicedemo2;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import com.lee.webservicedemo2.util.WebServiceUtil;
/**
* 注意添加网络访问权限:<uses-permission android:name="android.permission.INTERNET"/>
* 测试手机系统的环境:Android 4.3
*
* */
public class MainActivity extends Activity {
private TextView tv_addr;
Handler handler = null;
String addr = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_addr = ((TextView)findViewById(R.id.tv_location));
//使用Handler更新UI
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
if(msg.what == 0x100){
tv_addr.setText(addr);
}
}
};
findViewById(R.id.commit_btn).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//主线程不可访问网络
new Thread(new Runnable() {
@Override
public void run() {
try {
String mobileName = ((EditText) findViewById(R.id.mobilenumber_edit))
.getText().toString().trim();
//至少7位才能查询
if(mobileName.length() < 7){
addr = null;
handler.sendEmptyMessage(0x100);
return;
}
//String temp = WebServiceUtil.getAddressGet(MainActivity.this, mobileName);//GET method
String temp = WebServiceUtil.getAddressHttpClientPost(MainActivity.this, mobileName);//使用不同的网络访问方式
if (temp != null && temp.length() > 0) {
addr = temp.substring(temp.indexOf(":") + 1, temp.length()); //此处分隔符是中文:冒号
}else{
addr = null;
}
//使用Handler更新UI
handler.sendEmptyMessage(0x100);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
});
}
}
布局文件activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请输入手机号码:" />
<EditText
android:id="@+id/mobilenumber_edit"
android:layout_marginTop="4dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="至少7位号码"/>
<Button
android:id="@+id/commit_btn"
android:layout_marginTop="4dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询"/>
<TextView
android:id="@+id/tv_location"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>