最近学习Android访问网络资源的相关知识,然后实现了一个简单的手机号码归属地功能,特此记录一下。
一、主界面Activity实现
主界面的编写很简单,只是添加了一个EditText用于输入电话号码,一个Button点击查询按钮和一个TextView用于显示查询结果,这里不再赘述。直接看主界面的代码:
public class ActivityPhonePlace extends AppCompatActivity {
private EditText etPhoneNum; //输入电话号码的输入框
private Button btnFindPhonePlace; //点击查询电话号码归属地
private TextView tvShowPhonePlace; //号码归属地显示
//用于在新线程查询到结果之后,通知主线程更新界面
private Handler phoneHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0x000:
Phone phone = (Phone) msg.obj;
showInfo(phone);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_place);
init();//初始化界面组件
//点击查询手机号码的归属地
btnFindPhonePlace.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//查找手机号码的归属地涉及到网络请求,而自从android4.0之后,不允许在主线程中进行网络请求
new Thread(new Runnable() {
@Override
public void run() {
//获取输入的电话号码
String phoneNum=etPhoneNum.getText().toString().trim();
if(TextUtils.isEmpty(phoneNum)){
System.out.println("输入的电话号码为空");
}else {
try {
Phone phone=PhonePlaceUtils.parsePhone(phoneNum);
//查找到号码归属地之后,发送消息让主线程更新界面
Message message=Message.obtain();
message.what=0x000;
message.obj=phone;
phoneHandler.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}).start();
}
});
}
private void init(){
etPhoneNum=findViewById(R.id.etPhoneNum);//获取电话号码输入框对象
btnFindPhonePlace=findViewById(R.id.btnFindPhonePlace);//获取查询电话号码归属地按钮对象
tvShowPhonePlace=findViewById(R.id.tvShowPhonePlace); //获取显示电话号码归属地的TextView对象
}
private void showInfo(Phone phone) {
if (phone.getProvince() == null || phone.getProvince().equals("")) {
Looper.prepare();
Toast.makeText(this, "未查询到相关信息", Toast.LENGTH_SHORT).show();
Looper.loop();
} else {
tvShowPhonePlace.setText("省份:"+phone.getProvince()+'\n'+"城市:"+phone.getCity()+'\n'+"类型:"+phone.getCompany());
}
}
}
二、返回的实体数据类
定义实体类Phone,用于存储查询所返回的手机号码归属地信息
public class Phone {
private String province;
private String city;
private String company;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
}
三、后台代码编写
public class PhonePlaceUtils {
//手机号码归属地查询
public static Phone parsePhone(String phoneNumber) throws IOException, JSONException {
String result=null;
String url="http://apis.juhe.cn/mobile/get"; //请求接口地址
Map params=new HashMap(); //请求参数
params.put("phone",phoneNumber); //需要查询的手机号或手机号前7位
params.put("key","a77601ed6e5d3134e4e3aa406a193f6d"); //应用APPKEY(应用详细页查询)
params.put("dtype",""); //返回的数据格式,xml或者json,默认json
Phone phone=new Phone();//将解析后的查询结果存储在phone中
//获取查询所返回的结果
result=queryPhonePlace(url,params,"GET");
JSONObject object = new JSONObject(result);
if (object.getInt("error_code") == 0) {
JSONObject object1 = object.getJSONObject("result");
if (object1.has("province")) {
phone.setProvince((String) object1.get("province"));
}
if (object1.has("city")) {
phone.setCity((String) object1.get("city"));
}
if (object1.has("company")) {
phone.setCompany((String) object1.get("company"));
}
} else {
Log.e("ActivityPhonePlace", "parsePhone: error_code" + object.get("error_code") + ":" + object.get("reason"));
}
return phone;
}
/**
* 获取网络资源,通过接口地址获取手机号码归属地
* @param strUrl 请求接口地址
* @param params 请求参数
* @param method 请求方式
* @return 查询到的结果,以Json形式返回
* @throws IOException
*/
public static String queryPhonePlace(String strUrl,Map params,String method) throws IOException {
HttpURLConnection conn = null;
BufferedReader reader = null;
String rs = null;
try {
StringBuffer sb = new StringBuffer();
if (method == null || method.equals("GET")) {
strUrl = strUrl + "?" + urlencode(params);
}
URL url = new URL(strUrl);
conn = (HttpURLConnection) url.openConnection();//打开和URL之间的连接
//设置请求方式
if (method == null || method.equals("GET")) {
conn.setRequestMethod("GET");
} else {
conn.setRequestMethod("POST");
conn.setDoOutput(true);
}
//设置通用请求属性
conn.setRequestProperty("User-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36");
conn.setUseCaches(false);
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(false);
//建立实际的连接
conn.connect();
if (params != null && method.equals("POST")) {
try {
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(urlencode(params));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
InputStream is = conn.getInputStream();
//定义BufferedReader输入流来读取URL的响应
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sb.append(strRead);
}
rs = sb.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//使用finally块来关闭输入流和连接
finally {
if(reader!=null){
reader.close();
}
if (conn!=null){
conn.disconnect();
}
}
return rs;
}
//将map类型转为请求参数类型
public static String urlencode(Map<String,String> data) throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
for (Map.Entry i : data.entrySet()) {
sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue() + "", "UTF-8")).append("&");
}
return sb.toString();
}
}
四、运行结果