Android訪問中央氣象臺的天氣預報API得到天氣數據 .

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 plaincopy
  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] view plaincopy
  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 plaincopy
  1. 01|北京,02|上海,03|天津,04|重慶,05|黑龍江,06|吉林,07|遼寧,08|內蒙古,09|河北,10|山西,11|陝西,.....  
[plain] view plaincopy
  1. 01|北京,02|上海,03|天津,04|重慶,05|黑龍江,06|吉林,07|遼寧,08|內蒙古,09|河北,10|山西,11|陝西,.....  

然後通過這一次訪問得到的一級碼得到二級碼,如查找河北的:http://m.weather.com.cn/data5/city09.xml在city後加上一級碼得到:

[plain] view plaincopy
  1. 0901|石家莊,0902|保定,0903|張家口,0904|承德,0905|唐山,0906|廊坊,0907|滄州,0908|衡水,0909|邢臺,0910|邯鄲,0911|秦皇島  
[plain] view plaincopy
  1. 0901|石家莊,0902|保定,0903|張家口,0904|承德,0905|唐山,0906|廊坊,0907|滄州,0908|衡水,0909|邢臺,0910|邯鄲,0911|秦皇島  

然後再通過得到的二級碼得到三級的縣或區的編碼:如唐山:http://m.weather.com.cn/data5/city0905.xml:

[plain] view plaincopy
  1. 090501|唐山,090502|豐南,090503|豐潤,090504|灤縣,090505|灤南,090506|樂亭,090507|遷西,090508|玉田,090509|唐海,090510|遵化,090511|遷安  
[plain] view plaincopy
  1. 090501|唐山,090502|豐南,090503|豐潤,090504|灤縣,090505|灤南,090506|樂亭,090507|遷西,090508|玉田,090509|唐海,090510|遵化,090511|遷安  
最後由得到了三級碼就可能得到它對應的城市碼了,如訪問唐山.遷西:http://m.weather.com.cn/data5/city090507.xml得到:

[plain] view plaincopy
  1. 090507|101090507  
[plain] view plaincopy
  1. 090507|101090507  

則可知河北.唐山.遷西的城市編碼爲:101090507,得到它的天氣則通過訪問http://m.weather.com.cn/data/101090507.html得到。

    好了,相信通過上面的敘述,大家應該知道怎麼得到一個城市的天氣了;但接下來問題又來了,那我們怎樣通過Android訪問來得到全國任意一個地區的天氣呢?難道每一次訪問網絡三次得到城市碼,再用它訪問m.weather.com.cn這個網址得到天氣碼?天啊?這怎麼行!要知道我們手中的移動設備可不像電腦那樣"富有",流量是要扣錢的!!

   相信計算機算法好的同鞋已經想到了,就是通過程序將有的城市對應的天氣碼一次訪問到本地用android上的數據庫保存起來,這樣在每一次需要時,只需查詢一下數據庫就可以了,那關鍵就是怎樣遍歷得到所有的城市碼,現給出本人的遍歷代碼(來自於本人天氣預報系統):

[java] view plaincopy
  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();  
[java] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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. }  
[java] view plaincopy
  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 plaincopy
  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.     }  
[java] view plaincopy
  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開始故存在不匹配問題。爲了準確起見,大家還是自己遍歷一個數據庫,小子我由於近期較忙暫時不會對上面內容作更改{^_^},再次感謝你們!

                      

發佈了11 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章