前幾日Android發佈了4.0 Icecream,昨天上網發現Begining Book中有Edition 3的版本,比對一下,仍是有至關的改動,不只僅增長了tablet的部分,對原有的章節有有一些修訂,先後的調整等等。先按Edtion 2的順序看,相同章節的看Edtion 3,而後回頭看Edition 3的Chapter 2四、25(E2的36)、2六、2七、2八、2九、4四、4五、4六、47幾個新增章節。同時將模擬器改成Android 2.3的版本,已適應可能新增的改動。html
訪問Internet是設備的一個重要用戶,以前學習過如何嵌入Webkit,此外咱們能夠經過API來訪問Intenet。Android提供Apache HttpClient庫,基於此,其餘協議,能夠視爲在HTTP封裝的格式,例如XML,JSON等。HTTP Client的詳細資料可在http://hc.apache.org/中獲取。node
Android提供三個XML的解析器: 一、傳統的W3C DOM parser(org.w3c.dom); 二、SAX解析器(org.xml.sax); 三、以前Android學習筆記(三八):資源resource(上)中使用XmlPullParser。 另外提供JSON解析器(org.json)。固然也可使用第三方的解析器。 實現的步驟以下:android
下面是一個天氣widget的小例子,採用HttpClient,是以哦那個HttpGet發出對某個URL(google的天氣查詢網絡頁面)請求,返回xml格式的天氣信息,從中分析,並將結果經過WebKit Browser的方式程序,下面是查找廣州天氣的返回。在例子中,第一學習HttpClient的用法,第二也學習XML的解析,這次採用W3C DOM解析器,經過NodeList和Element來進行分析。web
<xml_api_reply version="1">
<weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0">
<forecast_information> <!-- 查詢地點信息,只給出準備分析的部分 -->
… …
<postal_code data="廣州"/>
<forecast_date data="2011-10-27"/>
</forecast_information>
<current_conditions> <!-- 給出當前的天氣狀況,只顯示準備分析的部分 -->
<condition data="局部多雲"/>
<temp_c data="27"/>
<humidity data="溼度: 48%"/>
<icon data="/ig/images/weather/partly_cloudy.gif"/>
<wind_condition data="風向: 北、風速:2 米/秒"/>
</current_conditions>
<forecast_conditions> <!-- 給出當每天氣預報 -->
<day_of_week data="週四"/>
<low data="21"/>
<high data="28"/>
<icon data="/ig/images/weather/mostly_sunny.gif"/>
<condition data="以晴爲主"/>
</forecast_conditions>
<forecast_conditions> <!-- 給出明每天氣預報 -->
... ...
</forecast_conditions>
<forecast_conditions> <!-- 給出後每天氣預報 -->
… …
</forecast_conditions>
<forecast_conditions> <!-- 給出第三每天氣預報 -->
… …
</forecast_conditions>
</weather>
</xml_api_reply>apache
程序代碼以下:json
(這個接口屬於iGoogle的私有接口,已經被關閉,能夠找其餘的weather api,例如http://www.wunderground.com/weather/api/。 Wei , 2012.9 )api
public class Chapter25Test1 extends Activity{
private WebView browser = null; //採用WebView來排版顯示的內容
private HttpClient client = null;
private List<Forecast> forecasts = new ArrayList<Forecast>(); //採用List來保存將來幾天的天氣狀況
private CurrentWeather currentCondition = null; //保存即時天氣狀況和地點時間
private String format = "http://www.google.com/ig/api?hl=zh-cn&weather=%1s"; //Google XML天氣信息的查詢API接口
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chapter_25_test1);
browser = (WebView) findViewById(R.id.c131_webkit);
//步驟一、建立HttpClient接口的對象,能夠經過DefaultHttpClient來建立。
client = new DefaultHttpClient();
}
protected void onResume() {
super.onResume();
updateForecast("廣州"); //步驟二、向Internet請求廣州的天氣信息,獲取信息,並呈現
}
protected void onDestroy() {
super.onDestroy();
//步驟三、釋放HttpClient的資源,此步沒詳細跟蹤,按字面估計如一直鏈接無回覆,則在Activity Destroy的時候,終止鏈接
client.getConnectionManager().shutdown();
}
//步驟二、向Internet請求廣州的天氣信息,獲取信息,並呈現
private void updateForecast(String citycode ){
String url = String.format(format, citycode);
//步驟2.一、生成HttpGet請求,並經過execute( )向Internet發出,在responseHandler中獲得返回值。
HttpGet getMethod = new HttpGet(url);
try{
ResponseHandler<String> responseHandle = new BasicResponseHandler();
String responseBody = client.execute(getMethod,responseHandle);
buildForecasts(responseBody); //步驟2.2 從返回中獲取天氣信息
String page = generatePage(); //步驟2.3 經過HTML在webkit browser中呈現
browser.loadDataWithBaseURL(null, page, "text/html", "UTF-8", null);
}catch(Throwable t){
Toast.makeText(this,"Request failed : "+ t.toString(), 5000).show();
}
}
//步驟2.2 從返回中獲取天氣信息,注意這種帶throws Exception的寫法
private void buildForecasts(String raw) throws Exception{
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(raw)));
//獲取即時天氣信息和地點、時間信息,方式和後面獲取將來天氣預報同樣,較爲繁瑣,略過,信息存放在currentCondition中
…. ….
//對於XML<node_name node_attribute=attribute_valule> node_vaule </node_name>
NodeList furCondition = doc.getElementsByTagName("forecast_conditions");
//有將來四日天氣預報,分別取出
for(int i = 0 ; i < furCondition.getLength(); i ++){
Element e = (Element)furCondition.item(i);
addWeather(e);
}
}
private void addWeather( Element e){
Forecast fc = new Forecast(getWeatherAttribute(e,"day_of_week"),
getWeatherAttribute(e,"low"),
getWeatherAttribute(e,"high"),
getWeatherAttribute(e,"icon"),
getWeatherAttribute(e,"condition"));
forecasts.add(fc);
}
//下面是從每組Element中讀取所需信息,另外補充的是若是愛用Node,例如e.getFirstClide()獲取,也能夠 node.getAttributes().getNamedItem("data").getNodeValue() 來得到攜帶的屬性值
private String getWeatherAttribute(Element e, String name){
NodeList t = e.getElementsByTagName(name);
Element a = (Element)t.item(0);
return a.getAttribute("data");
}
//步驟2.3 經過HTML在webkit browser中呈現
private String generatePage(){
StringBuilder bufResult = new StringBuilder("<html><body><table width=\"100%\">");
bufResult.append("<h2><font color=\"red\">" + currentCondition.getCity() + "</font></h2>\n");
… … //顯示即時信息
bufResult.append ("<table><tr><th width=\"25%\">Time</th>"+
"<th width=\"25%\">溫度</th><th colspan=\"2\" width=\"50%\">天氣狀況</th></tr>");
for(Forecast forecast : forecasts){
bufResult.append("<tr><td align=\"center\">");
bufResult.append(forecast.getDate());
bufResult.append("</td><td align=\"center\">");
bufResult.append(forecast.getTemperature());
bufResult.append("</td><td align=\"right\">");
bufResult.append(forecast.getCondition());
bufResult.append("</td><td align=\"left\"><img src=\"http://www.google.com/");
bufResult.append(forecast.getIcon());
bufResult.append("\"></td></tr>");
}
bufResult.append("</table></body></html>");
return bufResult.toString();
}
private class Forecast{
…. /* 存放天氣預報信息,並提供get獲取方法*/ …..
}
private class CurrentWeather{
…. /* 存放當前天氣、時間、地點,並提供get獲取方法*/ ….
}
} cookie
經過經緯度獲取當地天氣網絡
在Google的天氣預報api中,也是能夠輸入經緯度,格式爲:http://www.google.com/ig/api?hl=zh-cn&weather=,,,23080000,113170000,這是廣州的經緯度。Android能夠經過GPS獲取經緯度,而後所謂輸入參數,能夠獲得當前所在地的天氣。在模擬器中,能夠經過預先配置經緯度來進行個模擬。先打開模擬器,而後在Eclipse的菜單Window -> Open Perspective -> DDMS,進入配置,可在Control Panel中設置所需的經緯度。如右圖所示。多線程
定位服務之後再學習。
須要注意
若是是要使用SSL協議,HttpClient並不支持。主要是由於須要決定如何處理SSL證書,是否接受全部證書,包括私有或者已通過期的正確,或者是否須要提示用戶。
簡單的HttpClient在缺省下做爲單線程使用。若是須要多線程,能夠設置HttpClient支持多線程。
AndroidHttpClient
從Android2.2(API level 8)開始,可使用AndroidHttpClient類,在android.net.http中,是HttpClient接口的一個實現,就如例子中的DefaultHttpClient。經過這個類,能夠進行SSL管理;可經過靜態方法newInstance來直接填寫userAgent(report in your HTTP requests)並獲取AndroidHttpClient的實例,能夠在HTTP頭能增長date信息,支持gzip壓縮的內容。
和傳統的DefaultHttpClient不一樣,AndroidHttpClient不會自動保存cookies,可經過HttpContext對象來處理。
此外,AndroidHttpClient不容許主線程使用,只能在後臺線程運行。這點須要特別注意。
相關連接:個人Andriod開發相關文章