Android访问中央气象台的天气预报API得到天气数据

原址:http://m.blog.csdn.net/blog/hgy2011/7853375#

 

http://flash.weather.com.cn/wmaps/xml/china.xml 
能够获取国内各省及省会城市的天气,可以通过pyName载入各省内城市的天气 
如:河北省 pyName="hebei" 
http://flash.weather.com.cn/wmaps/xml/hebei.xml 
就可以载入河北省各城市天气,可以通过pyName="shijiazhuang" 
载入石家庄的详细天气 
http://flash.weather.com.cn/wmaps/xml/shijiazhuang.xml 
"http://flash.weather.com.cn/wmaps/xml/"+place+".xml" 
内容说明 
state1="0" //天气图标1 
state2="0" //天气图标2 
stateDetailed="晴" //天气说明 
tem1="9" //最高气温 
tem2="1" //最低气温 
temNow="2" //当前实况气温 
windState="南风转北风小于3级" //风向风速预报 
windDir="西北风" //当前实况风向 
windPower="小于3级" //当前实况风速 
humidity="77%" //湿度 
time="09:55" //发布时间 
url="101090101" //链接地 

有木有人能帮忙解析一下他的xml


在用Android获取天气预报数据时,大家一定会首先想到Google的天气预报API,其实除了Google的天气预报API,免费的天气预报接口还有http://www.webservicex.net/globalweather.asmx?op=GetWeather、http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx和中央气象台的天气预报,这三个是我最近试过的都可以访问,网上其实还介绍的有www.ayandy.com,不过我没试过 ^_^

现在就来谈一谈这几个服务,google的就不说了,www.webservicex.net的这个是一个国外的,获取中国国内的有点麻烦,且只有当天的天气,所以果断放弃...呵呵

而webservice.webxml.com.cn的这个确实不错,访问的数据是来自中国气象局http://www.cma.gov.cn/ 数据的准确就不用说了,但他分为付费和免费的,免费的服务有点不稳定,我就曾遇到一回,所以也不是很好,最后就只剩下中央气象台的天气预报的API了,这个我不想说太多,虽然获取时你首先要知道对应的城市码,有点麻烦,其它的如稳定性与广阔性也是很一流的,它可以精确到县和区.下面就直奔主题:

这个服务的天气预报的请求地址是:http://m.weather.com.cn/data/101070201.html,这个文本就是城市天气URL,101070201代表的为对应地区的编码,执行URL,得到一个返回文本,是JSON格式的,如下(经过格式化):

[plain]  view plain copy print ?
  1. {
  2. "weatherinfo":{
  3. "city":"成都",
  4. "city_en":"chengdu",
  5. "date_y":"2011年11月30日",
  6. "date":"辛卯年",
  7. "week":"星期三",
  8. "fchh":"11",//预报发布时间
  9. "cityid":"101270101",
  10. "temp1":"13℃~10℃",
  11. "temp2":"14℃~6℃",
  12. "temp3":"13℃~5℃",
  13. "temp4":"14℃~8℃",
  14. "temp5":"10℃~8℃",
  15. "temp6":"11℃~6℃",
  16. "tempF1":"55.4℉~50℉",
  17. "tempF2":"57.2℉~42.8℉",
  18. "tempF3":"55.4℉~41℉",
  19. "tempF4":"57.2℉~46.4℉",
  20. "tempF5":"50℉~46.4℉",
  21. "tempF6":"51.8℉~42.8℉",
  22. "weather1":"阴转多云",
  23. "weather2":"多云转晴",
  24. "weather3":"多云转阴",
  25. "weather4":"阵雨",
  26. "weather5":"阵雨转小雨",
  27. "weather6":"小雨转阴",
  28. "img1":"2",
  29. "img2":"1",
  30. "img3":"1",
  31. "img4":"0",
  32. "img5":"1",
  33. "img6":"2",
  34. "img7":"3",
  35. "img8":"99",
  36. "img9":"3",
  37. "img10":"7",
  38. "img11":"7",
  39. "img12":"2",
  40. "img_single":"2",
  41. "img_title1":"阴",
  42. "img_title2":"多云",
  43. "img_title3":"多云",
  44. "img_title4":"晴",
  45. "img_title5":"多云",
  46. "img_title6":"阴",
  47. "img_title7":"阵雨",
  48. "img_title8":"阵雨",
  49. "img_title9":"阵雨",
  50. "img_title10":"小雨",
  51. "img_title11":"小雨",
  52. "img_title12":"阴",
  53. "img_title_single":"阴",
  54. "wind1":"北风小于3级",
  55. "wind2":"北风小于3级",
  56. "wind3":"北风小于3级",
  57. "wind4":"南风转北风小于3级",
  58. "wind5":"北风小于3级",
  59. "wind6":"北风小于3级",
  60. "fx1":"北风",
  61. "fx2":"北风",
  62. "fl1":"小于3级",
  63. "fl2":"小于3级",
  64. "fl3":"小于3级",
  65. "fl4":"小于3级",
  66. "fl5":"小于3级",
  67. "fl6":"小于3级",
  68. "index":"舒适",
  69. "index_d":"建议着薄型套装或牛仔衫裤等春秋过渡装。年老体弱者宜着套装、夹克衫等。",
  70. "index48":"舒适",
  71. "index48_d":"建议着薄型套装或牛仔衫裤等春秋过渡装。年老体弱者宜着套装、夹克衫等。",
  72. "index_uv":"最弱",
  73. "index48_uv":"弱",
  74. "index_xc":"适宜",
  75. "index_tr":"很适宜",
  76. "index_co":"较舒适",
  77. "st1":"14",
  78. "st2":"10",
  79. "st3":"14",
  80. "st4":"6",
  81. "st5":"13",
  82. "st6":"4",
  83. "index_cl":"较适宜",
  84. "index_ls":"不太适宜",
  85. "index_ag":"较易发"
  86. }
  87. }
Plain代码 
  1. {   
  2.     "weatherinfo":{  
  3.                      "city":"成都",  
  4.                      "city_en":"chengdu",  
  5.                      "date_y":"2011年11月30日",  
  6.                      "date":"辛卯年",  
  7.                      "week":"星期三",  
  8.                      "fchh":"11",           //预报发布时间  
  9.                      "cityid":"101270101",  
  10.                      "temp1":"13℃~10℃",  
  11.                      "temp2":"14℃~6℃",  
  12.                      "temp3":"13℃~5℃",  
  13.                      "temp4":"14℃~8℃",  
  14.                      "temp5":"10℃~8℃",  
  15.                      "temp6":"11℃~6℃",  
  16.                      "tempF1":"55.4℉~50℉",  
  17.                      "tempF2":"57.2℉~42.8℉",  
  18.                      "tempF3":"55.4℉~41℉",  
  19.                      "tempF4":"57.2℉~46.4℉",  
  20.                      "tempF5":"50℉~46.4℉",  
  21.                      "tempF6":"51.8℉~42.8℉",  
  22.                      "weather1":"阴转多云",  
  23.                      "weather2":"多云转晴",  
  24.                      "weather3":"多云转阴",  
  25.                      "weather4":"阵雨",  
  26.                      "weather5":"阵雨转小雨",  
  27.                      "weather6":"小雨转阴",  
  28.                      "img1":"2",  
  29.                      "img2":"1",  
  30.                      "img3":"1",  
  31.                      "img4":"0",  
  32.                      "img5":"1",  
  33.                      "img6":"2",  
  34.                      "img7":"3",  
  35.                      "img8":"99",  
  36.                      "img9":"3",  
  37.                      "img10":"7",  
  38.                      "img11":"7",  
  39.                      "img12":"2",  
  40.                      "img_single":"2",  
  41.                      "img_title1":"阴",  
  42.                      "img_title2":"多云",  
  43.                      "img_title3":"多云",  
  44.                      "img_title4":"晴",  
  45.                      "img_title5":"多云",  
  46.                      "img_title6":"阴",  
  47.                      "img_title7":"阵雨",  
  48.                      "img_title8":"阵雨",  
  49.                      "img_title9":"阵雨",  
  50.                      "img_title10":"小雨",  
  51.                      "img_title11":"小雨",  
  52.                      "img_title12":"阴",  
  53.                      "img_title_single":"阴",  
  54.                      "wind1":"北风小于3级",  
  55.                      "wind2":"北风小于3级",  
  56.                      "wind3":"北风小于3级",  
  57.                      "wind4":"南风转北风小于3级",  
  58.                      "wind5":"北风小于3级",  
  59.                      "wind6":"北风小于3级",  
  60.                      "fx1":"北风",  
  61.                      "fx2":"北风",  
  62.                      "fl1":"小于3级",  
  63.                      "fl2":"小于3级",  
  64.                      "fl3":"小于3级",  
  65.                      "fl4":"小于3级",  
  66.                      "fl5":"小于3级",  
  67.                      "fl6":"小于3级",  
  68.                      "index":"舒适",  
  69.                      "index_d":"建议着薄型套装或牛仔衫裤等春秋过渡装。年老体弱者宜着套装、夹克衫等。",  
  70.                      "index48":"舒适",  
  71.                      "index48_d":"建议着薄型套装或牛仔衫裤等春秋过渡装。年老体弱者宜着套装、夹克衫等。",  
  72.                      "index_uv":"最弱",  
  73.                      "index48_uv":"弱",  
  74.                      "index_xc":"适宜",  
  75.                      "index_tr":"很适宜",  
  76.                      "index_co":"较舒适",  
  77.                      "st1":"14",  
  78.                      "st2":"10",  
  79.                      "st3":"14",  
  80.                      "st4":"6",  
  81.                      "st5":"13",  
  82.                      "st6":"4",  
  83.                      "index_cl":"较适宜",  
  84.                      "index_ls":"不太适宜",  
  85.                      "index_ag":"较易发"  
  86.         }  
  87. }  
上面显示的信息一目了然,就不用我多说了(在得到天气数据的解析android2.2可用JSONObject对象参考: http://henzil.easymorse.com/?p=242),关键是获得对应地区的城市码了。

访问http://m.weather.com.cn/data5/city.xml得到一级列表(省、直辖市、自治区),结果用逗号隔开,id和城市名称使用竖线“|”隔开;结果示例如下:

[plain]  view plain copy print ?
  1. 01|北京,02|上海,03|天津,04|重庆,05|黑龙江,06|吉林,07|辽宁,08|内蒙古,09|河北,10|山西,11|陕西,.....
Plain代码 
  1. 01|北京,02|上海,03|天津,04|重庆,05|黑龙江,06|吉林,07|辽宁,08|内蒙古,09|河北,10|山西,11|陕西,.....  

然后通过这一次访问得到的一级码得到二级码,如查找河北的:http://m.weather.com.cn/data5/city09.xml在city后加上一级码得到:

[plain]  view plain copy print ?
  1. 0901|石家庄,0902|保定,0903|张家口,0904|承德,0905|唐山,0906|廊坊,0907|沧州,0908|衡水,0909|邢台,0910|邯郸,0911|秦皇岛
Plain代码 
  1. 0901|石家庄,0902|保定,0903|张家口,0904|承德,0905|唐山,0906|廊坊,0907|沧州,0908|衡水,0909|邢台,0910|邯郸,0911|秦皇岛  

然后再通过得到的二级码得到三级的县或区的编码:如唐山:http://m.weather.com.cn/data5/city0905.xml:

[plain]  view plain copy print ?
  1. 090501|唐山,090502|丰南,090503|丰润,090504|滦县,090505|滦南,090506|乐亭,090507|迁西,090508|玉田,090509|唐海,090510|遵化,090511|迁安
Plain代码 
  1. 090501|唐山,090502|丰南,090503|丰润,090504|滦县,090505|滦南,090506|乐亭,090507|迁西,090508|玉田,090509|唐海,090510|遵化,090511|迁安  
最后由得到了三级码就可能得到它对应的城市码了,如访问唐山.迁西:http://m.weather.com.cn/data5/city090507.xml得到:

[plain]  view plain copy print ?
  1. 090507|101090507
Plain代码 
  1. 090507|101090507  

则可知河北.唐山.迁西的城市编码为:101090507,得到它的天气则通过访问http://m.weather.com.cn/data/101090507.html得到。

好了,相信通过上面的叙述,大家应该知道怎么得到一个城市的天气了;但接下来问题又来了,那我们怎样通过Android访问来得到全国任意一个地区的天气呢?难道每一次访问网络三次得到城市码,再用它访问m.weather.com.cn这个网址得到天气码?天啊?这怎么行!要知道我们手中的移动设备可不像电脑那样"富有",流量是要扣钱的!!

相信计算机算法好的同鞋已经想到了,就是通过程序将有的城市对应的天气码一次访问到本地用android上的数据库保存起来,这样在每一次需要时,只需查询一下数据库就可以了,那关键就是怎样遍历得到所有的城市码,现给出本人的遍历代码(来自于本人天气预报系统):

[java]  view plain copy print ?
  1. //一个自定义的网络访问工具类
  2. WebAccessToolswebTools=newWebAccessTools(this);//这里的this为context对象
  3. //得到访问网络的内容
  4. StringwebContent=webTools.getWebContent("http://m.weather.com.cn/data5/city.xml");
  5. //第一次解析得到的为省份或一级直辖市
  6. String[][]provinces=WeaterInfoParser.parseCity(webContent);//WeatherInfoParser为自定义的一个解析字符串类
  7. String[]groups=newString[provinces.length];
  8. String[][]childs=newString[provinces.length][];
  9. String[][]cityCode=newString[provinces.length][];
  10. for(inti=0;i<provinces.length;i++){
  11. groups[i]=provinces[i][1];
  12. //由省份码来得到城市码
  13. StringBufferurlBuilder=newStringBuffer("http://m.weather.com.cn/data5/city");
  14. urlBuilder.append(provinces[i][0]);
  15. urlBuilder.append(".xml");
  16. webContent=webTools.getWebContent(urlBuilder.toString());
  17. String[][]citys=WeaterInfoParser.parseCity(webContent);
  18. //用于保存所的有二级市对应的towns县区
  19. String[][][]towns=newString[citys.length][][];
  20. //计算总的城镇数
  21. intsum=0;
  22. for(intj=0;j<citys.length;j++){
  23. //由城市码来得到地方码
  24. urlBuilder=newStringBuffer("http://m.weather.com.cn/data5/city");
  25. urlBuilder.append(citys[j][0]);
  26. urlBuilder.append(".xml");
  27. webContent=webTools.getWebContent(urlBuilder.toString());
  28. towns[j]=WeaterInfoParser.parseCity(webContent);
  29. sum=sum+towns[j].length;
  30. }
  31. childs[i]=newString[sum];
  32. cityCode[i]=newString[sum];
  33. sum=0;
  34. for(intj=0;j<citys.length;j++){
  35. for(intn=0;n<towns[j].length;n++){
  36. if(n==0)
  37. childs[i][sum]=towns[j][n][1];
  38. else
  39. childs[i][sum]=towns[j][0][1]+"."+towns[j][n][1];
  40. urlBuilder=newStringBuffer("http://m.weather.com.cn/data5/city");
  41. urlBuilder.append(towns[j][n][0]);
  42. urlBuilder.append(".xml");
  43. webContent=webTools.getWebContent(urlBuilder.toString());
  44. String[][]code=WeaterInfoParser.parseCity(webContent);
  45. cityCode[i][sum]=code[0][1];
  46. sum=sum+1;
  47. }
  48. }
  49. urlBuilder=null;
  50. }
  51. //=======这里得到的groups数组记录的是得到的34个一级地区字符串=====================
  52. //=======childs记录的是与groups数组对应的一级地区对应的市级别或县区的字符串名,如:上海.闵行的形式(上海市没有.为上海)===
  53. //=======cityCode和childs形式相同,只不过记录的为地区的城市码=====================
  54. //=======下面就是将得到的城市码保存到数据库中,这里建了二张表,省份表和城市表,城市表通过province_id与省份表关联===========
  55. //============================CreateDatabase================================
  56. //打开或创建一个数据库,数据库路径为:/data/data/包名/数据库文件
  57. Stringpath="/data"+Environment.getDataDirectory().getAbsolutePath()+"/com.weather.app/db_weather.db";
  58. SQLiteDatabasedatabase=SQLiteDatabase.openOrCreateDatabase
  59. (path,null);
  60. //创建一个省份表
  61. Stringsql="createtableprovinces(_idintegerprimarykeyautoincrement,nametext)";
  62. database.execSQL(sql);
  63. //创建城市表
  64. sql="createtablecitys(_idintegerprimarykeyautoincrement,province_idinteger,nametext,city_numtext)";
  65. database.execSQL(sql);
  66. //插入省份数据
  67. ContentValuescv=null;
  68. for(inti=0;i<provinces.length;i++){
  69. cv=newContentValues();
  70. cv.put("name",provinces[i][1]);
  71. database.insert("provinces",null,cv);
  72. }
  73. //插入城市数据
  74. for(inti=0;i<childs.length;i++){
  75. for(intj=0;j<childs[i].length;j++){
  76. cv=newContentValues();
  77. cv.put("province_id",i);
  78. cv.put("name",childs[i][j]);
  79. cv.put("city_num",cityCode[i][j]);
  80. database.insert("citys",null,cv);
  81. }
  82. }
  83. cv=null;
  84. database.close();
Java代码 
  1.  //一个自定义的网络访问工具类  
  2.  WebAccessTools webTools = new WebAccessTools(this);  //这里的this为context对象  
  3.  //得到访问网络的内容  
  4.  String webContent=webTools.getWebContent("http://m.weather.com.cn/data5/city.xml");  
  5.    
  6.  //第一次解析得到的为省份或一级直辖市  
  7.  String[][] provinces = WeaterInfoParser.parseCity(webContent);  //WeatherInfoParser为自定义的一个解析字符串类  
  8.  String[] groups = new String[provinces.length];  
  9.  String[][] childs = new String[provinces.length][];  
  10.  String[][] cityCode = new String[provinces.length][];  
  11.  for(int i=0; i< provinces.length; i++) {  
  12.     groups[i] = provinces[i][1];  
  13.     //由省份码来得到城市码  
  14.     StringBuffer urlBuilder= new StringBuffer("http://m.weather.com.cn/data5/city");  
  15.     urlBuilder.append(provinces[i][0]);  
  16.     urlBuilder.append(".xml");  
  17.     webContent = webTools.getWebContent(urlBuilder.toString());  
  18.     String[][] citys = WeaterInfoParser.parseCity(webContent);  
  19.     //用于保存所的有二级市对应的towns县区  
  20.     String[][][] towns = new String[citys.length][][];  
  21.     //计算总的城镇数  
  22.     int sum=0;  
  23.     for(int j=0; j<citys.length; j++) {  
  24.         //由城市码来得到地方码  
  25.         urlBuilder= new StringBuffer("http://m.weather.com.cn/data5/city");  
  26.         urlBuilder.append(citys[j][0]);  
  27.         urlBuilder.append(".xml");  
  28.         webContent = webTools.getWebContent(urlBuilder.toString());  
  29.         towns[j] = WeaterInfoParser.parseCity(webContent);  
  30.         sum = sum + towns[j].length;  
  31.     }  
  32.       
  33.     childs[i] = new String[sum];  
  34.     cityCode[i] = new String[sum];  
  35.       
  36.     sum=0;  
  37.     for(int j=0; j<citys.length; j++) {  
  38.         for(int n=0; n<towns[j].length; n++) {  
  39.             if(n==0)  
  40.                 childs[i][sum] = towns[j][n][1];  
  41.             else  
  42.                 childs[i][sum] = towns[j][0][1] + "." + towns[j][n][1];  
  43.               
  44.             urlBuilder= new StringBuffer("http://m.weather.com.cn/data5/city");  
  45.             urlBuilder.append(towns[j][n][0]);  
  46.             urlBuilder.append(".xml");  
  47.               
  48.             webContent = webTools.getWebContent(urlBuilder.toString());  
  49.             String[][] code=WeaterInfoParser.parseCity(webContent);  
  50.             cityCode[i][sum] = code[0][1];  
  51.             sum = sum + 1;  
  52.         }  
  53.     }  
  54.     urlBuilder=null;  
  55.  }  
  56.    
  57.  //=======这里得到的groups数组记录的是得到的34个一级地区字符串 =====================  
  58.  //=======childs记录的是与groups数组对应的一级地区对应的市级别或县区的字符串名,如:上海.闵行的形式(上海市没有.为上海)===  
  59.  //=======cityCode和childs形式相同,只不过记录的为地区的城市码=====================  
  60.  //=======下面就是将得到的城市码保存到数据库中,这里建了二张表,省份表和城市表,城市表通过province_id与省份表关联===========  
  61. //============================Create Database================================  
  62.  //打开或创建一个数据库,数据库路径为:/data/data/包名/数据库文件  
  63.  String path="/data"+ Environment.getDataDirectory().getAbsolutePath() + "/com.weather.app/db_weather.db";  
  64.    
  65.  SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase  
  66.                            (path, null);  
  67.  //创建一个省份表  
  68.  String sql="create table provinces (_id integer primary key autoincrement, name text)";  
  69.  database.execSQL(sql);  
  70.    
  71.  //创建城市表  
  72.  sql = "create table citys (_id integer primary key autoincrement, province_id integer, name text, city_num text)";  
  73.  database.execSQL(sql);  
  74.    
  75.  //插入省份数据  
  76.  ContentValues cv = null;  
  77.  for(int i=0; i<provinces.length; i++) {  
  78.     cv = new ContentValues();  
  79.     cv.put("name", provinces[i][1]);  
  80.     database.insert("provinces"null, cv);  
  81.  }  
  82.  //插入城市数据  
  83.  for(int i=0; i<childs.length; i++) {  
  84.     for(int j=0; j<childs[i].length; j++) {  
  85.         cv = new ContentValues();  
  86.         cv.put("province_id", i);  
  87.         cv.put("name", childs[i][j]);  
  88.         cv.put("city_num", cityCode[i][j]);  
  89.         database.insert("citys"null, cv);  
  90.     }  
  91.  }  
  92.  cv = null;  
  93.  database.close();  
下面给出WebAccessTools工具类:

[java]  view plain copy print ?
  1. publicclassWebAccessTools{
  2. /**
  3. *当前的Context上下文对象
  4. */
  5. privateContextcontext;
  6. /**
  7. *构造一个网站访问工具类
  8. *@paramcontext记录当前Activity中的Context上下文对象
  9. */
  10. publicWebAccessTools(Contextcontext){
  11. this.context=context;
  12. }
  13. /**
  14. *根据给定的url地址访问网络,得到响应内容(这里为GET方式访问)
  15. *@paramurl指定的url地址
  16. *@returnweb服务器响应的内容,为<code>String</code>类型,当访问失败时,返回为null
  17. */
  18. publicStringgetWebContent(Stringurl){
  19. //创建一个http请求对象
  20. HttpGetrequest=newHttpGet(url);
  21. //创建HttpParams以用来设置HTTP参数
  22. HttpParamsparams=newBasicHttpParams();
  23. //设置连接超时或响应超时
  24. HttpConnectionParams.setConnectionTimeout(params,3000);
  25. HttpConnectionParams.setSoTimeout(params,5000);
  26. //创建一个网络访问处理对象
  27. HttpClienthttpClient=newDefaultHttpClient(params);
  28. try{
  29. //执行请求参数项
  30. HttpResponseresponse=httpClient.execute(request);
  31. //判断是否请求成功
  32. if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
  33. //获得响应信息
  34. Stringcontent=EntityUtils.toString(response.getEntity());
  35. returncontent;
  36. }else{
  37. //网连接失败,使用Toast显示提示信息
  38. Toast.makeText(context,"网络访问失败,请检查您机器的联网设备!",Toast.LENGTH_LONG).show();
  39. }
  40. }catch(Exceptione){
  41. e.printStackTrace();
  42. }finally{
  43. //释放网络连接资源
  44. httpClient.getConnectionManager().shutdown();
  45. }
  46. returnnull;
  47. }
  48. }
Java代码 
  1. public class WebAccessTools {  
  2.       
  3.     /** 
  4.      * 当前的Context上下文对象 
  5.      */  
  6.     private Context context;  
  7.     /** 
  8.      * 构造一个网站访问工具类 
  9.      * @param context 记录当前Activity中的Context上下文对象 
  10.      */  
  11.     public WebAccessTools(Context context) {  
  12.         this.context = context;  
  13.     }  
  14.       
  15.     /** 
  16.      * 根据给定的url地址访问网络,得到响应内容(这里为GET方式访问) 
  17.      * @param url 指定的url地址 
  18.      * @return web服务器响应的内容,为<code>String</code>类型,当访问失败时,返回为null 
  19.      */  
  20.     public  String getWebContent(String url) {  
  21.         //创建一个http请求对象  
  22.         HttpGet request = new HttpGet(url);  
  23.         //创建HttpParams以用来设置HTTP参数  
  24.         HttpParams params=new BasicHttpParams();  
  25.         //设置连接超时或响应超时  
  26.         HttpConnectionParams.setConnectionTimeout(params, 3000);  
  27.         HttpConnectionParams.setSoTimeout(params, 5000);  
  28.         //创建一个网络访问处理对象  
  29.         HttpClient httpClient = new DefaultHttpClient(params);  
  30.         try{  
  31.             //执行请求参数项  
  32.             HttpResponse response = httpClient.execute(request);  
  33.             //判断是否请求成功  
  34.             if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
  35.                 //获得响应信息  
  36.                 String content = EntityUtils.toString(response.getEntity());  
  37.                 return content;  
  38.             } else {  
  39.                 //网连接失败,使用Toast显示提示信息  
  40.                 Toast.makeText(context, "网络访问失败,请检查您机器的联网设备!", Toast.LENGTH_LONG).show();  
  41.             }  
  42.               
  43.         }catch(Exception e) {  
  44.             e.printStackTrace();  
  45.         } finally {  
  46.             //释放网络连接资源  
  47.             httpClient.getConnectionManager().shutdown();  
  48.         }  
  49.         return null;  
  50.     }  
  51. }  
就一个方法.

下面的解析工具类也只一个方法:

[java]  view plain copy print ?
  1. publicclassWeaterInfoParser{
  2. /**
  3. *通过解析content,得到一个一维为城市编号,二维为城市名的二维数组
  4. *解析的字符串的形式为:<code>编号|城市名,编号|城市名,.....</code>
  5. *@paramcontent需要解析的字符串
  6. *@return封装有城市编码与名称的二维数组
  7. */
  8. publicstaticString[][]parseCity(Stringcontent){
  9. //判断content不为空
  10. if(content!=null&&content.trim().length()!=0){
  11. StringTokenizerst=newStringTokenizer(content,",");
  12. intcount=st.countTokens();
  13. String[][]citys=newString[count][2];
  14. inti=0,index=0;
  15. while(st.hasMoreTokens()){
  16. Stringcity=st.nextToken();
  17. index=city.indexOf('|');
  18. citys[i][0]=city.substring(0,index);
  19. citys[i][1]=city.substring(index+1);
  20. i=i+1;
  21. }
  22. returncitys;
  23. }
  24. returnnull;
  25. }
  26. }
Java代码 
  1. public class WeaterInfoParser {  
  2.       
  3.     /** 
  4.      * 通过解析content,得到一个一维为城市编号,二维为城市名的二维数组 
  5.      * 解析的字符串的形式为: <code>编号|城市名,编号|城市名,.....</code> 
  6.      * @param content 需要解析的字符串 
  7.      * @return 封装有城市编码与名称的二维数组 
  8.      */  
  9.     public static String[][] parseCity(String content) {  
  10.         //判断content不为空  
  11.         if(content!=null&&content.trim().length()!=0) {  
  12.             StringTokenizer st=new StringTokenizer(content, ",");  
  13.             int count = st.countTokens();  
  14.             String[][] citys = new String[count][2];  
  15.             int i=0, index=0;  
  16.             while(st.hasMoreTokens()) {  
  17.                 String city = st.nextToken();  
  18.                 index = city.indexOf('|');  
  19.                 citys[i][0] = city.substring(0, index);  
  20.                 citys[i][1] = city.substring(index+1);  
  21.                 i = i+1;  
  22.             }  
  23.             return citys;  
  24.         }  
  25.         return null;  
  26.     }  
  27. }  

如上,这样就得到了国内所有地区的城市码数据库文件了,上面的方法在模拟器中运行时很慢,数分钟才能出来结果,要有耐心^_^!!

其通过上面的代码我们得到最重要的是db_weather.db这个文件,在Android中我们只要得到了它就可在程序第一次运行时直接导入到/data/data/包名/databases目录中就行了,已后直接调用,

关于数据库的导入,实质上就是文件的复制,我们只需在将数据库文件放在程序包中的res/raw目录中在运行时复制到databases目录是就行了,下面同样给出导入代码:

[java]  view plain copy print ?
  1. //将res/raw中的城市数据库导入到安装的程序中的database目录下
  2. publicvoidimportInitDatabase(){
  3. //数据库的目录
  4. StringdirPath="/data/data/com.weather.app/databases";
  5. Filedir=newFile(dirPath);
  6. if(!dir.exists()){
  7. dir.mkdir();
  8. }
  9. //数据库文件
  10. Filedbfile=newFile(dir,"db_weather.db");
  11. try{
  12. if(!dbfile.exists()){
  13. dbfile.createNewFile();
  14. }
  15. //加载欲导入的数据库
  16. InputStreamis=this.getApplicationContext().getResources().openRawResource(R.raw.db_weather);
  17. FileOutputStreamfos=newFileOutputStream(dbfile);
  18. byte[]buffere=newbyte[is.available()];
  19. is.read(buffere);
  20. fos.write(buffere);
  21. is.close();
  22. fos.close();
  23. }catch(FileNotFoundExceptione){
  24. e.printStackTrace();
  25. }catch(IOExceptione){
  26. e.printStackTrace();
  27. }
  28. }
Java代码 
  1. //将res/raw中的城市数据库导入到安装的程序中的database目录下  
  2.     public void importInitDatabase() {  
  3.         //数据库的目录  
  4.         String dirPath="/data/data/com.weather.app/databases";  
  5.         File dir = new File(dirPath);  
  6.         if(!dir.exists()) {  
  7.             dir.mkdir();  
  8.         }  
  9.         //数据库文件  
  10.         File dbfile = new File(dir, "db_weather.db");  
  11.         try {  
  12.             if(!dbfile.exists()) {  
  13.                 dbfile.createNewFile();  
  14.             }  
  15.             //加载欲导入的数据库  
  16.             InputStream is = this.getApplicationContext().getResources().openRawResource(R.raw.db_weather);  
  17.             FileOutputStream fos = new FileOutputStream(dbfile);  
  18.             byte[] buffere=new byte[is.available()];  
  19.             is.read(buffere);  
  20.             fos.write(buffere);  
  21.             is.close();  
  22.             fos.close();  
  23.   
  24.         }catch(FileNotFoundException  e){  
  25.             e.printStackTrace();  
  26.         }catch(IOException e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.     }  


我得到的城市码数据库文件可到http://download.csdn.net/detail/xianqiang1/3896880下载


上面的是我从天气预报系统中截取的部分代码,如有错误,欢迎留言指出!!

参照文章:使用JACKSON解析JSON(HttpClient 3处理请求)http://sarin.iteye.com/blog/821534

声明:感谢summerxzg和kpiao,指出了数据库文件的错误:我使用sqlitebrowser工具查看了一下我生成的db文件,显示出的的城市码数为2566个而summerxzg指出的为2583条,我的为不全。kpiao指出的citys表中的province_id与provinces表中的id不对应是由于代码中的是citys表创建时province_id是由0开始,而provinces表中的自动增长是从1开始故存在不匹配问题。为了准确起见,大家还是自己遍历一个数据库,小子我由于近期较忙暂时不会对上面内容作更改{^_^},再次感谢你们!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值