许多平台诸如阿里、百度等都对外提供了一些付费的API服务,使用这些服务能够大量节省开发成本。在这里我将实现利用来电归属地API服务实现归属地查询。
首先新建一个Android项目,并创建一个Activity。
该Activity中包含一个搜索框(使用EditText),一个按钮(Button)和一个查询结果的文本框(TextView)。页面设计代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.amia.telquery.MainActivity">
<RelativeLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/telnum"
android:textAlignment="center"<!--设置文字居中-->
android:inputType="number"<!--输入类型设置为数字-->
android:background="#ffffff"<!--背景颜色-->
android:hint="要查询的电话号码"<!--提示文本-->
android:layout_width="match_parent"
android:layout_height="50dp" />
<Button
android:id="@+id/submit"
android:background="@drawable/searchbutton"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true" />
</RelativeLayout>
<TextView
android:id="@+id/result"
android:textSize="15dp"
android:paddingTop="20dp"<!--顶部的距离-->
android:lineSpacingMultiplier="2.0"<!--设置行距倍数-->
android:lineSpacingExtra="6dp"<!--设置行距大小-->
android:textAlignment="center"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
实现的效果如下:
MainActivity中声明组件:
private EditText telnum;
private Button submit;
private TextView resultView;
MainActivity的onCreate方法中找到对应的组件:
telnum=(EditText)findViewById(R.id.telnum);
submit=(Button)findViewById(R.id.submit);
resultView=(TextView)findViewById(R.id.result);
定义归属地结果类:
public class TelType {
private String prov;//省份
private String num;//号段
private String areaCode;//区号
private String name;//运营商名称
private String postCode;//邮编3
private String provCode;//此地区身份证开头几位
private int type;////1移动 2电信 3联通
private String city;
public String getProv() {
return prov;
}
public void setProv(String prov) {
this.prov = prov;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPostCode() {
return postCode;
}
public void setPostCode(String postCode) {
this.postCode = postCode;
}
public String getProvCode() {
return provCode;
}
public void setProvCode(String provCode) {
this.provCode = provCode;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
新建一个java类,命名为QueryTelAddress。定义自己申请的host、path、appcode:
private String host="***** ";
private String path="***";
private String method="GET ";
private String appcode="*******";
headers和query的定义:
private Map<String,String> headers=new HashMap<>();
private Map<String,String> querys=new HashMap<>();
单例模式获得该对象:
public static QueryTelAddress getQueryTelAddress() {
return queryTelAddress;
}
private static QueryTelAddress queryTelAddress=new QueryTelAddress();
构造方法私有:
private QueryTelAddress(){
headers.put("Authorization","APPCODE "+appcode);
}
生成链接,这个方法引用了
https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java这里的代码(如有侵权请私信联系本人,感谢):
private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
StringBuilder sbUrl = new StringBuilder();
sbUrl.append(host);
if (!StringUtils.isBlank(path)) {
sbUrl.append(path);
}
if (null != querys) {
StringBuilder sbQuery = new StringBuilder();
for (Map.Entry<String, String> query : querys.entrySet()) {
if (0 < sbQuery.length()) {
sbQuery.append("&");
}
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
sbQuery.append(query.getValue());
}
if (!StringUtils.isBlank(query.getKey())) {
sbQuery.append(query.getKey());
if (!StringUtils.isBlank(query.getValue())) {
sbQuery.append("=");
sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
}
}
}
if (0 < sbQuery.length()) {
sbUrl.append("?").append(sbQuery);
}
}
return sbUrl.toString();
}
查询:
public TelType query(String num){
HttpClient httpClient=new DefaultHttpClient();
TelType telType=null;
String result="";
HttpGet httpRequest=null;
HttpResponse httpResponse;
querys.put("num",num);
try{
String target =buildUrl(host,path,querys);//创建连接
httpRequest=new HttpGet(target);
httpRequest.setHeader("Authorization",headers.get("Authorization"));
httpResponse=httpClient.execute(httpRequest);
if(httpResponse.getStatusLine().getStatusCode()== HttpStatus.SC_OK){
result= EntityUtils.toString(httpResponse.getEntity());//获取放回的字符串
Log.e("result",result);
telType=resolveJSON(result);//将返回的JSON数据解析
}
}
catch(ClientProtocolException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
return telType;
}
解析JSON数据并生成java bean对象:
private TelType resolveJSON(String result){
TelType telType=null;
try {
JSONObject jsonObject = new JSONObject(result);
int res_code=jsonObject.getInt("showapi_res_code");//获取结果状态代码,参数请查询申请API的KEY
if(res_code==0){
telType=new TelType();
JSONObject telQueryResult=jsonObject.getJSONObject("showapi_res_body");//获得JSON对象,参数请查询你申请的API的KEY
HashMap<String,Object> res=changeToHash(telQueryResult);//将JSON对象中的字段转存到哈希表中
telType=changtoTelType(res);//转换为javabean对象
}
}
catch (JSONException e){
e.printStackTrace();
}
return telType;
}
将JSON对象的数据转存到哈希表中,参考了@战国剑 的Android解析——json解析为javabean(http://blog.youkuaiyun.com/yangzhaomuma/article/details/50995094,如有侵权请私信本人,感谢):
private HashMap<String,Object> changeToHash(JSONObject jsonObject){
HashMap<String,Object> result=new HashMap<>();
Iterator it=jsonObject.keys();
try {
while (it.hasNext()) {
String key = String.valueOf(it.next());
Object values = jsonObject.get(key);
result.put(key,values);
}
}
catch (JSONException e){
e.printStackTrace();
}
return result;
}
转换为java bean对象:
private TelType changtoTelType(HashMap<String,Object> res){
/*
参数请查询你申请的API的KEY
*/
TelType telType=new TelType();
telType.setProv(res.get("prov").toString());
telType.setNum(res.get("num").toString());
telType.setAreaCode(res.get("areaCode").toString());
telType.setName(res.get("name").toString());
telType.setPostCode(res.get("postCode").toString());
telType.setProvCode(res.get("provCode").toString());
telType.setType(Integer.parseInt(res.get("type").toString()));
telType.setCity(res.get("city").toString());
return telType;
}
在MainActivity的onCreate()方法中为submit按钮添加监听事件:
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resultView.setText("");
new Thread(new Runnable() {
@Override
public void run() {
String tel=telnum.getText().toString();
result=query.query(tel);
Message m=handler.obtainMessage();
handler.sendMessage(m);
}
}).start();
}
});
创建Handle对象:
private Handler handler=new Handler(){
public void handleMessage(Message msg){
if(result!=null){
resultView.setText(String.valueOf("省份:"+result.getProv()+"\n"
+"所在城市:"+result.getCity()+"\n"+"运营商:"+result.getName()+"\n"
+"邮政编码:"+result.getPostCode()));
}
else{
//错误提示对话框
AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);
builder.setTitle("查询失败!");
builder.setMessage("未能查询到该号码信息,请检查号码是否正确或者网络连接是否正常!");
builder.setPositiveButton("确定",null);
builder.show();
}
super.handleMessage(msg);
}
};
最终实现结果: