手机号码归属地查询
MobileAddressQuery
Android通过调用Webservice实现手机号码归属地查询
注:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx是本文webservice的提供商
具体的用法见:
http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?op=getMobileCodeInfo
android.os.NetworkOnMainThreadException
一个APP如果在主线程中请求网络操作,将会抛出此异常。Android这个设计是为了防止网络请求时间过长而导致界面假死的情况发生。
解决方案有两个,一个是使用StrictMode,二是使用线程来操作网络请求。
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">手机号码归属地查询</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="mobile">手机号码</string>
<string name="button">归属地查询</string>
<string name="error">查询失败</string>
</resources>
fragment_main.xml
<RelativeLayout 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: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="com.example.mobileaddressquery.MainActivity$PlaceholderFragment" >
<TextView
android:id="@+id/lblMobile"
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:layout_below="@id/lblMobile"
android:id="@+id/mobile"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/button"
android:id="@+id/buttonId"
android:layout_below="@id/mobile"
/>
<TextView
android:id="@+id/lblResult"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/buttonId" />
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mobileaddressquery"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<!-- 访问Internet权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.mobileaddressquery.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>
</manifest>
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/">
<mobileCode>$mobile</mobileCode>
<userID></userID>
</getMobileCodeInfo>
</soap12:Body>
</soap12:Envelope>
AddressService.java
package com.example.mobileaddressquery;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xmlpull.v1.XmlPullParser;
import android.util.Xml;
public class AddressService {
private static String readSoapFile(InputStream inStream, String mobile)
throws Exception {
byte[] data = StreamTool.readInputStream(inStream);
String soapxml = new String(data);
Map<String, String> params = new HashMap<String, String>();
params.put("mobile", mobile);
return replace(soapxml, params);
}
public static String replace(String xml, Map<String, String> params)
throws Exception {
String result = xml;
if (params != null && !params.isEmpty()) {
for (Map.Entry<String, String> entry : params.entrySet()) {
String name = "\\$" + entry.getKey();
Pattern pattern = Pattern.compile(name);
Matcher matcher = pattern.matcher(result);
if (matcher.find()) {
result = matcher.replaceAll(entry.getValue());
}
}
}
return result;
}
public static String getMobileAddress(InputStream inStream, String mobile)
throws Exception {
String soap = readSoapFile(inStream, mobile);
byte[] data = soap.getBytes();
URL url = new URL(
"http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setConnectTimeout(5 * 1000);
conn.setDoOutput(true);// 如果通过post提交数据,必须设置允许对外输出数据
conn.setRequestProperty("Content-Type",
"application/soap+xml; charset=utf-8");
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
if (conn.getResponseCode() == 200) {
return parseResponseXML(conn.getInputStream());
}
return null;
}
private static String parseResponseXML(InputStream inStream)
throws Exception {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(inStream, "UTF-8");
int eventType = parser.getEventType();// 产生第一个事件
while (eventType != XmlPullParser.END_DOCUMENT) {// 只要不是文档结束事件
switch (eventType) {
case XmlPullParser.START_TAG:
String name = parser.getName();// 获取解析器当前指向的元素的名称
if ("getMobileCodeInfoResult".equals(name)) {
return parser.nextText();
}
break;
}
eventType = parser.next();
}
return null;
}
}
StreamTool.java
package com.example.mobileaddressquery;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public class StreamTool {
/**
* 从输入流读取数据
*
* @param inStream
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
return outSteam.toByteArray();
}
}
MainActivity.java
package com.example.mobileaddressquery;
import java.io.InputStream;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
private EditText phoneSecEditText;
private TextView resultView;
private Button queryButton;
private static final String TAG = "MainActivity";
public MyThread thread;
public Handler handler;
@SuppressLint("HandlerLeak")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
phoneSecEditText = (EditText) this.findViewById(R.id.mobile);
resultView = (TextView) this.findViewById(R.id.lblResult);
queryButton = (Button) this.findViewById(R.id.buttonId);
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;
} else {
Thread t = new MyThread();
t.start();
}
}
});
// 创建handler对象
handler = new Handler() {
@SuppressLint("HandlerLeak")
public void handleMessage(Message msg) {
switch (msg.what) {
case 0x01:
Bundle bundle = new Bundle();
bundle = msg.getData();
Toast.makeText(MainActivity.this,
bundle.getString("result"), Toast.LENGTH_SHORT)
.show();
}
}
};
}
// 创建线程
public class MyThread extends Thread {
@Override
public void run() {
// 创建本线程的消息队列并初始化
Looper.prepare();
getTelephoneInfo();
// 开始运行消息队列
Looper.loop();
}
}
public void getTelephoneInfo() {
// 查询手机号码(段)信息
String mobile = phoneSecEditText.getText().toString();
InputStream inStream = this.getClass().getClassLoader()
.getResourceAsStream("sop12.xml");
try {
String address = AddressService.getMobileAddress(inStream, mobile);
// 获取返回的结果
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putString("result", address);
msg.setData(bundle);
msg.what = 0x01;
handler.handleMessage(msg);
// resultView.setText(address);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.toString());
Toast.makeText(getApplicationContext(), R.string.error, 1).show();
}
}
}