大作业(二)

3.2使用HTTP访问网络

Android上发送HTTP请求的方式一般有两个,HttpURLConnectionHttpClient,在这里我们使用HttpURLConnection

首先需要获取到HttpURLConnection的实例,一般只需new出一个URL对象,并传入目标的网络地址,然后调用一下openConnection()方法即可,如下所示:

 

URL url = new url(http://www.baidu.com);

HttpURLConnection connection =(HttpURLConnection) url.openConnection();

 

得到了HttpURLConnection的实例之后,我们可以设置一下HTTP请求所使用的方法。常用的方法主要有两个,GETPOSTGET表示希望从服务器那里获取数据,而POST则表示希望提交数据给服务器。接下来就可以进行设置连接超时、读取超时的毫秒数;之后再调用getInputStream()方法就可以获取到服务器返回的输入流了,剩下的任务就是对输入流进行读取;最后将连接关闭掉。

    下面我们就在com.wyd.search.common包中新建HttpUtils.java类,代码如下所示:

 public final class HttpUtils {

private static final String LOG_TAG = "HttpUtils Connect Tag";

public static String openUrl(String url, String method, Bundle params, String enc){

String response = null;

if(method.equals("GET")){

url = url + "?" + encodeUrl(params);

}

try {

Log.d(LOG_TAG, "Url:"+url);

    HttpURLConnection conn = (HttpURLConnection) new    

                        URL(url).openConnection();

conn.setRequestProperty("User-Agent", System.getProperties()

.getProperty("http.agent"));

conn.setReadTimeout(10000); //设置超时时间

if(method.equals("POST")){

conn.setRequestMethod("POST");

conn.setDoOutput(true);

conn.getOutputStream().write(encodeUrl(params).getBytes("UTF-8"));

}

response = read(conn.getInputStream(),enc);

} catch (Exception e) {

Log.e(LOG_TAG, e.getMessage());

throw new RuntimeException(e.getMessage(),e);

}

return response;

}

private static String read(InputStream in, String enc) throws IOException {

StringBuilder sb = new StringBuilder();

InputStreamReader isr = null;

BufferedReader r = null;

if(enc != null){

//按指定的编码读入流

r = new BufferedReader(new InputStreamReader(in,enc), 1000);

}else{

//按默认的编码读入

r = new BufferedReader(new InputStreamReader(in), 1000);

}

for (String line = r.readLine(); line != null; line = r.readLine()) {

sb.append(line);

}

in.close();

return sb.toString();

}

public static String encodeUrl(Bundle parameters) {

if (parameters == null)

return "";

StringBuilder sb = new StringBuilder();

boolean first = true;

for (String key : parameters.keySet()) {

if (first)

first = false;

else

sb.append("&");

sb.append(key + "=" + parameters.getString(key));

}

return sb.toString();

}

}

3.3查询活动的搜索条件

我们在查询的时候,会有一些限制条件,比如说查询的IP是否合法、手机号码位数是否够......因此要进行一些限制。

我们在com.wyd.search.common包中新建ActivityUtils类,代码如下:

 

public final class ActivityUtils {

 

public static void showDialog(Context context, String button,String title, String message){

new AlertDialog.Builder(context)

   .setTitle(title)

   .setMessage(message)

   .setNeutralButton(button, null)

   .create()

   .show();

}

//校验str是否为空或为""

public static boolean validateNull(String str){

if(str == null || str.equals("")){

return false;

}else{

return true;

}

}

//校验str中是否全部是数字,用到了正则表达式

public static boolean validateNumber(String str){

Pattern pattern = Pattern.compile("[0-9]");

Matcher matcher = pattern.matcher(str);

return matcher.matches();

}

//校验Ip是否合法

public static boolean validateIp(String str){

Pattern pattern = Pattern.compile("[0-9],.");

Matcher matcher = pattern.matcher(str);

return matcher.matches();

}

}

4  查询工具创建

在第二阶段,我们进行具体实体类的编程,首先我们需要申请相应的接口数据,这个我们可以轻松在聚合数据网站上得到,然后把具体的功能一个个实现,我们在第一步新建的包中新建相应的查询实体类。具体实现如下:

4.1快递单号查询

com.wyd.search.ems包中新建Ems.java类,代码如下:

 

public class Ems implements Serializable {

private static final long serialVersionUID = 1L;

// 变量声明

private String message; //消息体

private String time; //时间

private String context; //状态

private String status; //返回值状态:0,查询失败;1:查询成功

private String company; //快递公司名称

private String order; //单号

 

接下来新建快递查询的监听类EmsListener,代码如下:

 

public class EmsSearch extends Activity {

private Spinner emsCompanies;

private EditText emsOrder;

private Resources res;

private String[] emsCodes;

private int pos = 0;

private String selectedCom;

private Search search;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.ems);

        res = this.getResources();

        emsCodes = res.getStringArray(R.array.ems_code);

        emsOrder = (EditText)this.findViewById(R.id.ems_order);

        emsCompanies = (Spinner)this.findViewById(R.id.ems_com);

            ArrayAdapter<CharSequence> adapter =   

                ArrayAdapter.createFromResource(this, R.array.ems_company,   

            android.R.layout.simple_spinner_item);

            adapter.setDropDownViewResource(android.R.layout.

                simple_spinner_dropdown_item);

        emsCompanies.setAdapter(adapter);

            emsCompanies.setOnItemSelectedListener(selectedListener);

        search = new Search();

    }

private AdapterView.OnItemSelectedListener selectedListener = new      

            AdapterView.OnItemSelectedListener() {

public void onItemSelected(AdapterView<?> parent, View v, int position,

   long id) {

// 用户选择了,记录下用户选择的公司所对应的代码

pos = position;

selectedCom = (String)parent.getItemAtPosition(position);

}

public void onNothingSelected(AdapterView<?> parent) {

// TODO Auto-generated method stub

}

};   

public String getCode(){

return emsCodes[pos-1]; //因为城市spinner中多了一个请选择

}

//检验是否选择了一个快递公司

public boolean validateSelect(){

if(pos < 1 || pos > emsCodes.length){

return false;

}else{

return true;

}

}

    public void onClick(View v){

    if(v.getId() == R.id.ems_search){

    String order = this.emsOrder.getText().toString().trim();

    if(this.validateSelect()){

    if(ActivityUtils.validateNull(order)){

    //校验成功

    String companyCode = this.getCode();

    Bundle bundle = new Bundle();

    bundle.putString("company", selectedCom);

    bundle.putString("order", order);

    this.getIntent().putExtras(bundle); //记录下公司和单号

    EmsListener listener = new EmsListener(this);

    search.asyncRequest(companyCode, order, listener);

    }else{

    ActivityUtils.showDialog(this, res.getString(R.string.ok), res.getString(R.string.tip), res.getString(R.string.ems_order_error));

    }

    }else{

    ActivityUtils.showDialog(this, res.getString(R.string.ok), res.getString(R.string.tip), res.getString(R.string.ems_noselect));

    }

    }

    }

}

最后就是查询后返回相应的数据,新建SearchResult.java,代码如下:

 

public class SearchResult extends Activity {

 

private TextView emsCompany,emsOrder,emsTime,emsContext;

private Resources res;

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

this.requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.ems_info);

this.emsCompany = (TextView)this.findViewById(R.id.ems_company);

this.emsOrder = (TextView)this.findViewById(R.id.ems_order);

this.emsTime = (TextView)this.findViewById(R.id.ems_time);

this.emsContext = (TextView)this.findViewById(R.id.ems_context);

res = this.getResources();

this.showResult();

}

private void showResult() {

Bundle bundle = this.getIntent().getExtras();

Ems ems = (Ems) bundle.getSerializable("ems");

if(ems != null){

if(ems.getStatus().equals("1")){

this.emsCompany.setText(ems.getCompany());

this.emsOrder.setText(ems.getOrder());

this.emsTime.setText(ems.getTime());

this.emsContext.setText(ems.getContext());

}else{

         ActivityUtils.showDialog(this,res.getString(R.string.ok), res.getString(R.string.tip),  

            ems.getMessage());

  }

}else{

        ActivityUtils.showDialog(this, res.getString(R.string.ok), res.getString(R.string.tip),   

            res.getString(R.string.ems_fail));

}

   }

}

运行程序,效果如下:

 

 

 

 

 

4.1手机号归属地查询

我们首先在com.wyd.search.telephone包中新建手机号归属地查询的实体类Telephone.java,代码如下:

 

public class Telephone implements Serializable{

private static final long serialVersionUID = 1L;

private String mobile; //

private String queryResult; //返回结果

private String province; //省份

private String city; //城市

private String areaCode; //区号

private String postCode; //

private String corp; //

private String card; //卡类型

 

我们可在聚合数据网站上申请数据,然后应用网站提供的接口,通过对申请的数据得知,手机号码的查询涵盖中国移动、中国联通和中国电信,查询的结果包括省份、城市、区号和卡类型。

 

接下来新建快递查询的监听类TelephoneListener,代码如下:

 

public class TelephoneListener implements RequestListener {

private TelephoneSearch context;

private ProgressDialog progress;

private Resources res;

public TelephoneListener(TelephoneSearch context){

this.context = context;

res = context.getResources();

     progress=ProgressDialog.show(context,res.getString(R.string.

           tel_searching),

     res.getString(R.string.getting));

    progress.show();

}

@Override

public void onComplete(final String result) {

this.context.runOnUiThread(new Runnable() {

@Override

public void run() {

Intent intent = new Intent();

Bundle bundle = new Bundle();

bundle.putSerializable("telephone", parseJSON(result));

intent.putExtras(bundle);

intent.setClass(context, SearchResult.class);

progress.dismiss();

context.startActivity(intent);

}

});

}

public void onException(Exception e) {

this.context.runOnUiThread(new Runnable() {

public void run() {

if(progress != null){

progress.dismiss();

}

        ActivityUtils.showDialog(context, res.getString(R.string.ok),    res.getString(R.string.tip), res.getString(R.string.get_nothing)); }

});

}

public Telephone parseJSON(String jsonStr){

Telephone tel = null;

jsonStr = jsonStr.substring(14, jsonStr.length()-2);

try {

tel = new Telephone();

JSONObject jsonObj = new JSONObject(jsonStr);

tel.setMobile(jsonObj.getString("Mobile"));

tel.setQueryResult(jsonObj.getString("QueryResult"));

tel.setProvince(jsonObj.getString("Province"));

tel.setCity(jsonObj.getString("City"));

tel.setAreaCode(jsonObj.getString("AreaCode"));

tel.setPostCode(jsonObj.getString("PostCode"));

tel.setCorp(jsonObj.getString("Corp"));

tel.setCard(jsonObj.getString("Card"));

} catch (JSONException e) {

Log.e(LOG_TAG, e.getMessage());

}

return tel;

}

private static final String LOG_TAG = "TelephoneListener";

}

 

我们从聚合数据网站上获得的数据可以使用XMLJSON两种方法解析,这里我们解析成JSON格式数据,因为相对于XMLJSON的主要优势在于它的体积更小,在网络上传输的时候可以更省流量。

然而,解析JSON数据的方法也有很多,我们使用JSONObject,首先将HTTP请求的地址加上,然后在得到了服务器返回的数据后调用parseJSONWithJSONObject()方法来解析数据。每个JSONObject对象中包含Mobile、Province、AreaCode和Card等这些数据,接下来只需要调用getString()方法将这些数据取出,并打印出来即可。

最后就是更新UI的问题,要将解析出来的数据显示出来,代码如下:

public class SearchResult extends Activity {

private TextView mobile,province,city,areacode,postcode,card;

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.telephone_info);

        mobile = (TextView)this.findViewById(R.id.telephone_mobile);

        province = (TextView)this.findViewById(R.id.telephone_province);

        city = (TextView)this.findViewById(R.id.telephone_city);

        areacode = (TextView)this.findViewById(R.id.telephone_areacode);

        postcode = (TextView)this.findViewById(R.id.telephone_postcode);

        card = (TextView)this.findViewById(R.id.telephone_card);

        this.showResult();

    }

  

    public void showResult(){

     Intent intent = this.getIntent();

     Bundle bundle = intent.getExtras();

     Telephone tel = (Telephone)bundle.getSerializable("telephone");

     if(tel != null){

         mobile.setText(tel.getMobile());

         province.setText(tel.getProvince());

         city.setText(tel.getCity());

         areacode.setText(tel.getAreaCode());

         postcode.setText(tel.getPostCode());

         card.setText(tel.getCard());

     }

    }

}

4.3天气的查询

我们首先在com.wyd.search.weather包中新建手机号归属地查询的实体类Weather.java,代码如下:

public class Weather implements Serializable {

private static final long serialVersionUID = 13835783478884L;

private String day; //星期

private String date; //日期

private String low; //最低温度

private String high; //最高温度

private String code; //天气状况码

private String text; //天气状况码,对应的天气类型

 

接着我偶们继续新建Search类,代码如下:

public class Search {

//这里使用的是雅虎天气查询url

private static final String   HTTP_URL="http://weather.yahooapis.com/forecastrss";

private static final String METHOD = "GET";

private static final String LOG_TAG = "com.search.weather.Search";

 

public String request(String woeid){

if(woeid != null){

Bundle params = new Bundle();

params.putString("w", woeid); //城市对应的id

params.putString("u", "c"); //华氏温度是f,摄氏温度是c。这里采用摄氏度

return HttpUtils.openUrl(HTTP_URL, METHOD, params,null);

}else{

return null;

}

}

//异步封装

public void asyncRequest(final String city, final RequestListener listener){

//子线程中更新UI

new Thread(new Runnable() {

@Override

public void run() {

try {

String response = request(city);

listener.onComplete(response);

} catch (Exception e) {

Log.e(LOG_TAG, e.getMessage());

listener.onException(e);

}

}

}).start();

}

}

下面创建WeatherListener.java,代码如下:

public class WeatherListener implements RequestListener {

private WeatherSearch context;

private ProgressDialog progress;

private Resources res;

public WeatherListener(WeatherSearch context){

this.context = context;

res = this.context.getResources();

this.progress = ProgressDialog.show(context, res.getString(R.string.wea_searching), res.getString(R.string.getting));

this.progress.show();

}

public void onComplete(final String result) {

context.runOnUiThread(new Runnable() {

public void run() {

try {

InputStream is = null;

is = new ByteArrayInputStream(result.getBytes("UTF-8"));

List<Weather> results = WeatherPullParser.getData(is);

if(results.size()>=2){

Weather today = results.get(0);

Weather tomorrow = results.get(1);

Intent intent = new Intent();

Bundle bundle = new Bundle();

bundle.putSerializable("today", today);

bundle.putSerializable("tomorrow", tomorrow);

intent.putExtras(bundle);

intent.setClass(context, SearchResult.class);

if(progress != null){

progress.dismiss();

}

context.startActivity(intent);

}else{

if(progress != null){

progress.dismiss();

}

ActivityUtils.showDialog(context, res.getString(R.string.ok), res.getString(R.string.tip), res.getString(R.string.xml_error));

}

 

} catch (UnsupportedEncodingException e) {

Log.e(LOG_TAG, e.getMessage());

ActivityUtils.showDialog(context, res.getString(R.string.ok), res.getString(R.string.tip), res.getString(R.string.xml_error));

}

}

});

}

public void onException(final Exception e) {

context.runOnUiThread(new Runnable() {

@Override

public void run() {

if(progress != null){

progress.dismiss();

}

ActivityUtils.showDialog(context, res.getString(R.string.ok), res.getString(R.string.tip), res.getString(R.string.get_nothing));

}

});

}

private static final String LOG_TAG = "WeatherListener";

}

 

然后我们就要对服务器返回的数据进行解析了,由于这里我们用的是雅虎天气提供的数据,所以这里我们运用Pull的解析方式。

新建WeatherPullParser.java,代码如下:

public class WeatherPullParser {

public static List<Weather> getData(InputStream reader){

List<Weather> result = null;

XmlPullParser parser = Xml.newPullParser();

Weather wea = null;

String tagName = null;

try {

parser.setInput(reader, "UTF-8");

int eventCode = parser.getEventType(); //返回事件码类型

while(eventCode != XmlPullParser.END_DOCUMENT){

switch(eventCode){

case XmlPullParser.START_DOCUMENT:

//初始化

result = new ArrayList<Weather>();

break;

case XmlPullParser.START_TAG:

//一个元素的开始

tagName = parser.getName(); //获取当前标签的名称

if(tagName.equalsIgnoreCase("forecast")){

wea = new Weather();

wea.setDay(parser.getAttributeValue(null, "day"));

wea.setDate(parser.getAttributeValue(null, "date"));

wea.setLow(parser.getAttributeValue(null, "low"));

wea.setHigh(parser.getAttributeValue(null, "high"));

wea.setText(parser.getAttributeValue(null, "text"));

wea.setCode(parser.getAttributeValue(null, "code"));

result.add(wea);

}

break;

}

eventCode = parser.next(); //解析下一个元素

}

} catch (Exception e) {

Log.e("WeatherPullParser", e.getMessage());

}

return result;

}

}

 

最后就是就是就将解析出阿里的数据显示出来,在这个包下新建SearchResult.java,代码如下:

public class SearchResult extends Activity {

private TextView today,tomorrow,low1,low2,high1,high2;

private Resources res;

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.weather_info);

        today = (TextView)this.findViewById(R.id.wea_today);

        tomorrow = (TextView)this.findViewById(R.id.wea_tomorrow);

        low1 = (TextView)this.findViewById(R.id.wea_low);

        low2 = (TextView)this.findViewById(R.id.wea_low2);

        high1 = (TextView)this.findViewById(R.id.wea_high);

        high2 = (TextView)this.findViewById(R.id.wea_high2);

        res = this.getResources();

        this.showResult();

    }

 

private void showResult() {

Intent intent = this.getIntent();

Bundle bundle = intent.getExtras();

Weather w_today = (Weather)bundle.getSerializable("today");

Weather w_tomorrow = (Weather)bundle.getSerializable("tomorrow");

String unit = res.getString(R.string.wea_unit);

if(w_today != null){

String today_codition = this.getCondition(w_today.getCode()); //获取code对应的天气

today.setText(today_codition);

low1.setText(w_today.getLow()+unit);

high1.setText(w_today.getHigh()+unit);

}

if(w_tomorrow != null){

String tommorrow_condition = this.getCondition(w_tomorrow.getCode());

tomorrow.setText(tommorrow_condition);

low2.setText(w_tomorrow.getLow()+unit);

high2.setText(w_tomorrow.getHigh()+unit);

}

}

//根据代码获取对应的天气信息。在weather的string-array中匹配

private String getCondition(String code) {

 

String[] weathers = res.getStringArray(R.array.weather);

int temp = Integer.parseInt(code);

if(temp < 48 && temp >= 0){

return weathers[temp];

}

return res.getString(R.string.wea_undefine);

}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值