版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p><b> 目錄</b></p><p><b> 摘要1</b></p><p><b> 需求分析2</b></p><p><b> 一、開發(fā)背景2</b></p><p> 二、項目需求分析2</p>
2、<p><b> 總體設計2</b></p><p><b> 一、系統(tǒng)規(guī)劃2</b></p><p> 二、系統(tǒng)功能界面3</p><p> 1. 設置預報城市界面:3</p><p> 2.天氣顯示界面:4</p><p> 3.Widg
3、et 桌面小部件界面:5</p><p><b> 三.設計目標6</b></p><p><b> 系統(tǒng)設計6</b></p><p> 一、開發(fā)及運行環(huán)境6</p><p><b> 二、數(shù)據(jù)庫設計6</b></p><p> 三
4、、主要方法及步驟7</p><p> 四、主要方法及技術7</p><p><b> 主要模塊7</b></p><p><b> 一、項目框架7</b></p><p> 二、主要功能實現(xiàn)8</p><p> 1.獲取城市碼 db_weather.db
5、數(shù)據(jù)庫文件8</p><p> 2.實現(xiàn)可伸縮性列表的的構建與過濾12</p><p> 3.GPS 定位功能的實現(xiàn)15</p><p> 4.Widget 窗體小部件的更新18</p><p><b> 功能測試19</b></p><p><b> 結論23&l
6、t;/b></p><p><b> 摘要</b></p><p> Window 操作系統(tǒng)的誕生成就了微軟帝國,同時也造就了 PC 時代的繁榮,然而如今,以 Android 和 iPhone 手機為代表的智能移動設備的發(fā)明與互聯(lián)網(wǎng)云技術的興起卻敲響了 PC 時代的喪鐘!這也預示著移動互聯(lián)網(wǎng)時代(3G)已經(jīng)來臨。</p><p>
7、在這個互聯(lián)網(wǎng)繁榮的時代,有一顆超新星,以它獨特性能優(yōu)勢與人性化的 UI 設計使它在短短的幾年迅速的占領了智能移動設備的市場份額,它就是 Google 的 Android!這也意味著 Google 在移動互聯(lián)網(wǎng)時代開始搶跑并領跑。</p><p> Android 是基于 Linux 平臺完全開源的手機操作系統(tǒng),同時開發(fā)語言為Java,這對于 Java 開發(fā)的我們是何等的誘人,程序員的技術要與時代同行,因此我選擇
8、了以 Android 為平臺的手機天氣預報系統(tǒng)來作為我的畢業(yè)設計,選擇手機天氣預報系統(tǒng)不僅可以提升技術,同時也很實用,為人們時刻了解天氣狀況和出行帶來了方便。</p><p><b> 1</b></p><p><b> 需求分析</b></p><p><b> 一、開發(fā)背景</b><
9、/p><p> 近幾年來隨著 3G 技術成熟和智能手機的不斷普及,移動應用的需求與日俱增,移動應用開發(fā)成為當下最熱門的技術之一。在 Google 和 Android 手機聯(lián)盟的共同推動下,Android 在眾多移動應用開發(fā)平臺中脫穎而出。Android 是一個真正意義上的開源智能手機操作系統(tǒng),該系統(tǒng)一經(jīng)推出立即受到全球移動設備廠商和開發(fā)者的熱捧。為順應潮流,本設計旨在搭載 Android 的移動設備上運行,實現(xiàn)天氣
10、狀況的實時動態(tài)更新與顯示,方便人們的出行與生活。</p><p><b> 二、項目需求分析</b></p><p> 根據(jù)功能的需求,分析此項目的主要功能應具備以下幾點:</p><p> 精確查詢定位全國各地城市未來幾天內的實時天氣狀況</p><p> 系統(tǒng)要具的實用性,符合用戶查看信息習慣,界面設計優(yōu)美&
11、lt;/p><p> 系統(tǒng)要具有穩(wěn)定性,且在一定程度上節(jié)省流量的開銷</p><p><b> 總體設計</b></p><p><b> 一、系統(tǒng)規(guī)劃</b></p><p> 由上述的需求,現(xiàn)將系統(tǒng)分為三大模塊:天氣顯示界面模塊、預報城市設置模塊與 Widget 桌面小部件模塊。各系統(tǒng)模塊功
12、能如下:</p><p> 1). 天氣顯示界面模塊</p><p> 顯示指定城市三天內的天氣狀況,包括日期、城市名稱、溫度、風力與當日的建議,用戶可通過按菜單鍵來顯示菜單更新當前天氣與設置天氣顯示的界面背景,以及跳轉至設置預報城市界面來更換預報城市。</p><p> 2). 預報城市設置模塊</p><p> 由自動設置預報城市
13、與手動設置二部分組成,自動設置實現(xiàn) GPS 定位功能,自動確定當前用戶所在地;而手動設置則通過可伸展性下拉列表單擊選擇系統(tǒng)數(shù)據(jù)庫中預存的城市來進行設置,同時為了方便用戶查找,支持以輸入框的形式來過濾查詢預報城市。當單擊選中城市時跳轉至天氣顯示界面,來顯示該城市當三天內的天氣狀況;第一次運行時自動跳到該界面。</p><p> 3). Widget 桌面小部件模塊</p><p> 為了
14、方便用戶實時了解天氣狀況,特別添加在 Android 系統(tǒng)桌面上顯示當前天氣與時間的天氣小部件,使用戶拿起手機的第一時刻就能了解天氣,同時當用戶單擊小部件時,自動跳轉至天氣顯示界面,顯示三天內的詳細天氣。</p><p><b> 2</b></p><p><b> 二、系統(tǒng)功能界面</b></p><p><
15、b> 設置預報城市界面:</b></p><p> 1.1 當?shù)谝淮芜\行程序時,跳轉至城市設置界面進行預報城市的選擇:</p><p> 1.2 用戶可以通過單擊選擇“定位當前城市”的方式調用系統(tǒng) GPS 功能自動定位預報城市:</p><p><b> 3</b></p><p> 1.3
16、用戶可通過輸入框過濾查詢當前系統(tǒng)中預存的城市:</p><p><b> 2.天氣顯示界面:</b></p><p> 2.1 選擇了預報城市后,系統(tǒng)跳轉至天氣顯示界面,顯示該城市三天內的實時天氣:</p><p><b> 4</b></p><p> 2.2 在天氣界面中用戶可通過按菜單
17、鍵來調出菜單,選擇城市,更新天氣與更換背景:</p><p> 3.Widget 桌面小部件界面:</p><p> 方便用戶第一時間了解天氣動態(tài),添加 widget 顯示功能界面:</p><p><b> 5</b></p><p><b> 三.設計目標</b></p>
18、<p> 設計完成一個實用穩(wěn)定的天氣預報系統(tǒng),同時要廉價使其能滿足大部分用戶的需求,因此針對上述要求,本設計應滿足:</p><p> 系統(tǒng)能及時的返反饋指定預報城市的天氣情況</p><p> 自動定位用戶所在城市,支持 GPS 定位</p><p> 節(jié)省流量開銷,規(guī)定在指定的時間間隔內才更新天氣,其它時段顯示緩存的天氣</p>
19、<p> 操作方便快捷,使用簡單,界面設計美觀大方,支持 widget</p><p><b> 系統(tǒng)設計</b></p><p><b> 一、開發(fā)及運行環(huán)境</b></p><p><b> JDK1.6.10</b></p><p> Eclipse3
20、.5</p><p> Android Development Toolkit (ADT) 15.0.0</p><p> Android 2.2 及以上</p><p> Windows XP 及以上</p><p><b> 二、數(shù)據(jù)庫設計</b></p><p> 由于在本系統(tǒng)中是
21、通過中央氣象臺的 WebService 提供的 API 訪問得到的天氣預報,在查詢指定城市的天氣時,需要用到它提供的城市碼,而城市碼相對穩(wěn)定不變,所以在構建系統(tǒng)時將其事先通過 Android 的網(wǎng)絡訪問技術將其緩沖到本地 SQLite 數(shù)據(jù)庫進行保存起來,方便以后的查詢,同時節(jié)省了流量開銷。綜上所述在本地建立 db_weather.db 的數(shù)據(jù)庫,其中的表結構如下:</p><p> 其中只存在兩個表: pro
22、vices 和 citys</p><p> City 中存在 city_num 用天氣的查詢,同時還存在外鍵 province_id 與 provices 表形成 1 對 n 的關系。</p><p><b> 6</b></p><p><b> 三、主要方法及步驟</b></p><p>
23、; 搭建 Android 開發(fā)環(huán)境,并建立一個 android2.2 版本名為 WeatherSystem</p><p><b> 項目</b></p><p> 首先編寫網(wǎng)絡訪問代碼,訪問 http://m.weather.com.cn/data5/city.xml 中央氣象站解析得到所有城市碼并導出保存得到的 db_weather.db 數(shù)據(jù)文件</
24、p><p> 在程序第一次運行時,將 db_weatcher.db 數(shù)據(jù)庫文件導入到應用程序數(shù)據(jù)庫中</p><p> 建立設置城市界面,讀取數(shù)據(jù)庫文件,獲取省份,城市以及對應的城市碼。</p><p> 接收用戶選擇的城市碼,訪問:http://m.weather.com.cn/data/<城市碼>.html</p><p>
25、<b> 得到天氣信息</b></p><p> 解析天氣信息,將城市碼及天氣信息緩沖下來,并為其設置有效時間,方便下次啟動時直接得到天氣信息,過期則從網(wǎng)上更新</p><p> 定時由保存的城市碼更新天氣信息</p><p><b> 四、主要方法及技術</b></p><p> And
26、roid 手機的界面 UI 設計</p><p> Android 的網(wǎng)絡通信</p><p> Android 的廣播</p><p><b> GPS 調用解析</b></p><p> Widget 小部件編程</p><p> XML 與 JSON 解析</p>&
27、lt;p> SQLite 數(shù)據(jù)庫操作</p><p> Android 文件操作</p><p><b> 主要模塊</b></p><p><b> 一、項目框架</b></p><p> 在裝有 ADT 插件的 Eclipse 中新建一個名為 WeatherSystem 的 An
28、droid2.2 版本的項目,</p><p> 項目主要文件結構如下:</p><p> WeatherSystem</p><p><b> 7</b></p><p><b> |</b></p><p> |_AndroidManifest.xml</
29、p><p><b> 二、主要功能實現(xiàn)</b></p><p> 1.獲取城市碼 db_weather.db 數(shù)據(jù)庫文件</p><p> 獲取全國各地的城市碼,是通過訪問中央氣象局網(wǎng)從省份直轄市到城鎮(zhèn)一級一級深入得到的,獲得一個地區(qū)的城市碼總共需要訪問 4 次網(wǎng)絡,分別如下:</p><p> 訪問 http://
30、m.weather.com.cn/data5/city.xml 得到省份直轄市列表與它的編號:</p><p> 01|北京,02|上海,03|天津,04|重慶,05|黑龍江,06|吉林,07|遼寧,08|內蒙古,…</p><p> 訪問 http://m.weather.com.cn/data5/city<省份編號>.xml 得到該省份直轄市的城市編號(如訪問山東:ht
31、tp://m.weather.com.cn/data5/city12.xml)</p><p> 1201|濟南,1202|青島,1203|淄博,1204|德州,1205|煙臺,1206|濰坊,……</p><p> 訪問 http://m.weather.com.cn/data5/city<城市編號>.xml 得到該城市的縣區(qū)編號(如訪問濟南:http://m.weath
32、er.com.cn/data5/city1201.xml)</p><p> 120101|濟南,120102|長清,120103|商河,120104|章丘,120105|平陰,….</p><p> 訪問 http://m.weather.com.cn/data5/city<縣區(qū)編號>.xml 得到該縣區(qū)的城市碼(如訪問長清:http://m.weather.com.cn
33、/data5/city120102.xml)</p><p> 120102|101120102</p><p><b> 8</b></p><p> 首先實現(xiàn)上述功能需使用Android的網(wǎng)絡訪問技術,故編寫工具類</p><p> WebAccessTools 類如下:</p><p
34、><b> /**</b></p><p> 根據(jù)給定的url地址訪問網(wǎng)絡,得到響應內容(這里為GET方式訪問)</p><p> @param url 指定的url地址</p><p> @return web服務器響應的內容,為<code>String</code>類型,當訪問失敗時,返回為null *
35、/</p><p> public String getWebContent(String url) {</p><p> //創(chuàng)建一個http請求對象</p><p> HttpGet request = new HttpGet(url);</p><p> //創(chuàng)建HttpParams以用來設置HTTP參數(shù)</p>
36、<p> HttpParams params=new BasicHttpParams();</p><p> //設置連接超時或響應超時</p><p> HttpConnectionParams.setConnectionTimeout(params, 3000);</p><p> HttpConnectionParams.setSoTime
37、out(params, 5000);</p><p> //創(chuàng)建一個網(wǎng)絡訪問處理對象</p><p> HttpClient httpClient = new DefaultHttpClient(params); try{</p><p><b> //執(zhí)行請求參數(shù)項</b></p><p> HttpRespo
38、nse response = httpClient.execute(request);</p><p> //判斷是否請求成功</p><p> if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {</p><p><b> //獲得響應信息</b></
39、p><p> String content = EntityUtils.toString(response.getEntity()); return content;</p><p><b> } else {</b></p><p> //網(wǎng)連接失敗,使用Toast顯示提示信息</p><p> Toast.mak
40、eText(context, "網(wǎng)絡訪問失敗,請檢查您機器的聯(lián)網(wǎng)設備!", Toast.LENGTH_LONG).show();</p><p><b> }</b></p><p> }catch(Exception e) {</p><p> e.printStackTrace();</p><
41、p> } finally {</p><p> //釋放網(wǎng)絡連接資源</p><p> httpClient.getConnectionManager().shutdown();</p><p><b> }</b></p><p> return null;</p><p>&l
42、t;b> }</b></p><p> 由上面訪問的可知,得到的編碼與名稱都是“編碼|名稱”的形式,因此在這也編寫一個解析得到城市碼的工具類 WeatherInfoParser,用于解析從服務器中得到的城市碼:</p><p><b> 9</b></p><p><b> /**</b><
43、/p><p> 通過解析content,得到一個一維為城市編號,二維為城市名的二維數(shù)組</p><p> 解析的字符串的形式為: <code>編號|城市名,編號|城市名,.....</code></p><p> @param content 需要解析的字符串</p><p> @return 封裝有城市編碼與名稱
44、的二維數(shù)組</p><p><b> */</b></p><p> public static String[][] parseCity(String content) {</p><p> //判斷content不為空</p><p> if(content!=null&&content.tr
45、im().length()!=0) {</p><p> StringTokenizer st=new StringTokenizer(content, ","); int count = st.countTokens();</p><p> String[][] citys = new String[count][2];</p><p>
46、 int i=0, index=0;</p><p> while(st.hasMoreTokens()) {</p><p> String city = st.nextToken();</p><p> index = city.indexOf('|');</p><p> citys[i][0] = city.s
47、ubstring(0, index);</p><p> citys[i][1] = city.substring(index+1);</p><p><b> i = i+1;</b></p><p><b> }</b></p><p> return citys;</p>
48、<p><b> }</b></p><p> return null;</p><p><b> }</b></p><p> 編寫這兩個類后現(xiàn)在就是編寫從服務器端用程序遍歷得到全國各地的城市名與</p><p> 城市碼,并將它們分別的保存在 String[][] prov
49、inces 數(shù)組,String[][] childs 數(shù)組與</p><p> String[][] cityCode 中:</p><p> WebAccessTools webTools = new WebAccessTools(this); //得到訪問網(wǎng)絡的內容</p><p> String webContent=webTools.getWebCon
50、tent("http://m.weather.com.cn/data5/city.xml"); //第一次解析得到的為省份或一級直轄市</p><p> String[][] provinces = WeaterInfoParser.parseCity(webContent); String[] groups = new String[provinces.length];</p>
51、<p> String[][] childs = new String[provinces.length][]; String[][] cityCode = new String[provinces.length][]; for(int i=0; i< provinces.length; i++) { groups[i] = provinces[i][1];</p><p> //由省份碼
52、來得到城市碼</p><p> StringBuffer urlBuilder= new StringBuffer("http://m.weather.com.cn/data5/city");</p><p> urlBuilder.append(provinces[i][0]);</p><p> urlBuilder.append(&q
53、uot;.xml");</p><p> webContent = webTools.getWebContent(urlBuilder.toString());</p><p><b> 10</b></p><p> String[][] citys = WeaterInfoParser.parseCity(webConten
54、t); //用于保存所的有towns</p><p> String[][][] towns = new String[citys.length][][]; //計算總的城鎮(zhèn)數(shù)</p><p> int sum=0;</p><p> for( int j=0; j<citys.length; j++) {</p><p> /
55、/由城市碼來得到地方碼</p><p> urlBuilder= new StringBuffer("http://m.weather.com.cn/data5/city");</p><p> urlBuilder.append(citys[j][0]);</p><p> urlBuilder.append(".xml&quo
56、t;);</p><p> webContent = webTools.getWebContent(urlBuilder.toString()); towns[j] = WeaterInfoParser.parseCity(webContent);</p><p> sum = sum + towns[j].length;</p><p><b>
57、}</b></p><p> childs[i] = new String[sum];</p><p> cityCode[i] = new String[sum];</p><p><b> sum=0;</b></p><p> for( int j=0; j<citys.length; j
58、++) {</p><p> for(int n=0; n<towns[j].length; n++) {</p><p><b> if(n==0)</b></p><p> childs[i][sum] = towns[j][n][1];</p><p><b> else</b>
59、</p><p> childs[i][sum] = towns[j][0][1] + "." + towns[j][n][1];</p><p> urlBuilder= new StringBuffer("http://m.weather.com.cn/data5/city"); urlBuilder.append(towns[j][n][0
60、]); urlBuilder.append(".xml");</p><p> webContent = webTools.getWebContent(urlBuilder.toString()); String[][] code=WeaterInfoParser.parseCity(webContent); cityCode[i][sum] = code[0][1]; sum = sum
61、+ 1;</p><p><b> }</b></p><p><b> }</b></p><p> urlBuilder=null;</p><p><b> }</b></p><p> 接下來就是將得到的上面的三個數(shù)組建立數(shù)據(jù)庫文件 d
62、b_weather.db 保存起來,用到 android.database.sqlite.SQLiteDatabase 類的靜態(tài)方法:</p><p> SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory)來創(chuàng)建一個數(shù)據(jù)庫文件,其中的 path 表示數(shù)據(jù)庫存放的路徑,而 factory 中游標工廠,這里可將它設為空,從而得
63、到 SQLiteDatabase 對象,則再調用它的 execSQL(String sql)方法來執(zhí)行保存數(shù)據(jù)庫的操作,從而將上面的三個數(shù)組轉換為數(shù)據(jù)庫中的數(shù)</p><p> 據(jù),最后使用 ADT 插件中的 DDMS 工具將得到的數(shù)據(jù)庫文件從 Android 模擬器</p><p><b> 11</b></p><p> 中導出,最終
64、就得到了 db_weather.db 文件。以后上述的代碼就可以不使用,直接將 db_weather.db 文件放入資源文件夾 res 目錄中的 raw 目錄中,則在程序第一次運行時導入到/data/data/com.weather.app/databases 目錄中就行了,其中關于數(shù)據(jù)庫的導入實際是 Java 中文件的復制。</p><p> 2.實現(xiàn)可伸縮性列表的的構建與過濾</p><
65、p> 實現(xiàn)可伸縮性列表是通過繼承 android.widget.BaseExpandableListAdapter 適配器實現(xiàn)的,其中主要實現(xiàn)它的 public View getGroupView()得列表的一級列表和 public void getChildView()得到列表的二級子列表實現(xiàn)的,在這里由于只是實現(xiàn)文本顯示功能,故用 TextView 組件來填充就行了,如果要構造這個自定義的適配器,則只需在提供存放省份直轄市的
66、一級列表的數(shù)組 String[] groups 和存放對應的城鎮(zhèn)的二級列表的 String[][] childs 就行了。</p><p> 同時為了兼具過濾功能,還要需再實現(xiàn) android.widget.Filterable 接口,這個接口有一個 getFilter()返回 Filter 過濾器的列表,故還要提供一個 Filter 過濾類,在本系統(tǒng)中,實現(xiàn)的是一個內部類 CityFilter,它繼承 and
67、roid.widget.Filter 類,覆蓋實現(xiàn)了兩個方法,一個是 performFiltering()得到 FilterResults 過濾結果對象方法,另一個是根據(jù)得到的 FilterResults 對象更新適配器的 publishResults()方法。</p><p> 其中的 performFiltering(CharSequence constraint)方法的實現(xiàn)是通過 constraint 這
68、個關鍵字以省份直轄市為單位進行匹配,如果匹配成功,則添加該省份以下的所有城市,如果匹配不成功,則再逐一與這個省份的下的城市配匹,則只添加匹配的城市,其中匹配的結果放在 Map<Integer, ArrayList<Integer>> values 這樣的向量中,再由新建的 FilterResults 封裝返回,(具體實現(xiàn)如下):</p><p> 首先是對關鍵字進行判斷是否為空,如為空則
69、由 values 添加所有省份與城市,其中的 allGroups 和 allChilds 保存的是所有的省份與對應的城市:</p><p> //當過濾條件為空時,返回所有的省份與城市</p><p> if(constraint == null || constraint.length() == 0) {</p><p> for(int i=0; i<
70、;allGroups.length; i++) { ArrayList<Integer> index = new ArrayList<Integer>(); //添加所有與之對應的城市</p><p> for(int j=0; j<allChilds[i].length; j++) { index.add(j);</p><p><b> }&
71、lt;/b></p><p> values.put(i, index);</p><p><b> }</b></p><p><b> }</b></p><p> 如果關鍵字 constraint 不為空,則以省份為單位進行匹配,省份匹配的添加下面的所在城鎮(zhèn),如果不匹配,則進行步
72、深入匹配城鎮(zhèn),添加符合條件的城鎮(zhèn):</p><p><b> 12</b></p><p> String filterStr = constraint.toString(); for (int i=0; i<allGroups.length; i++) {</p><p> //查找省名是否包含用戶輸入的字符串</p>
73、<p> if(allGroups[i].contains(filterStr)) { ArrayList<Integer> index = new ArrayList<Integer>(); //添加所有與之對應的城市</p><p> for(int j=0; j<allChilds[i].length; j++) { index.add(j);</p&g
74、t;<p><b> }</b></p><p> values.put(i, index);</p><p><b> } else {</b></p><p> ArrayList<Integer> index = new ArrayList<Integer>(); //如
75、果省份名沒有,則查找它下面的城市名是否包含</p><p> for(int j=0; j<allChilds[i].length; j++) { if(allChilds[i][j].contains(filterStr)) {</p><p> index.add(j);</p><p><b> }</b></p>
76、<p><b> }</b></p><p> //如果添加進入了城市,說明存在,則它的省份也添加進去</p><p> if(index.size() > 0) {</p><p> values.put(i, index);</p><p><b> } else {</
77、b></p><p> index = null;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> 得到過濾的結果后將其用 FilterResource
78、封裝后返回:</p><p> FilterResults results = new FilterResults(); results.values = values; results.count = values.size();</p><p> 另外的 publishResults(CharSequence constraint, FilterResults results)方法
79、就是根據(jù)上面得到的 results 對象來得到新的 String[] groups 與 String[][] Childs 數(shù)組,再調用 BaseExpandableListAdapter 父類的 notifyDataSetChanged()方法來更新列表,從而實現(xiàn)過濾后結果的顯示(具體實現(xiàn)如下):</p><p> 首先將參數(shù) FiltersResuls 對象轉換為 Map<Integer, Array
80、List<Integer>> filterResult,然后來判斷過濾后的結果長度時否為 0,如果長度為 0 則說明過濾后的結果為空,則調用父類的 notifyDataSetInvalidated()方法來阻止列表的更新:</p><p> 如果長度不為 0,則說明存在過濾結果,則將它轉換為 groups 數(shù)組與 childs</p><p> 數(shù)組,并調用 noti
81、fyDataSetChanged()方法實再更新:</p><p><b> 13</b></p><p> String[] newGroups = new String[count];</p><p> String[][] newChilds = new String[count][];</p><p>
82、int index = 0;</p><p> int length = 0;</p><p> //得到新的groups和childs</p><p> for(int i=0; i<allGroups.length; i++) { if(filterResult.containsKey(i)) {</p><p> newG
83、roups[index] = allGroups[i];</p><p><b> //符合條件的城市</b></p><p> ArrayList<Integer> citys = filterResult.get(i); length = citys.size();</p><p> newChilds[index] =
84、new String[length]; for(int j = 0; j< length; j++) {</p><p> newChilds[index][j] = allChilds[i][citys.get(j)];</p><p><b> }</b></p><p> index = index + 1;</p>
85、;<p><b> }</b></p><p><b> }</b></p><p> //設置groups和childs</p><p> groups = newGroups;</p><p> childs = newChilds;</p><p&g
86、t;<b> //更新列表</b></p><p> notifyDataSetChanged();</p><p> //判斷是否展開列表</p><p> count = getGroupCount();</p><p> if(count < 34) {</p><p>&l
87、t;b> //展開伸縮性列表</b></p><p> for(int i=0; i<count; i++) {</p><p> provinceList.expandGroup(i);</p><p><b> }</b></p><p><b> } else {<
88、/b></p><p><b> //收縮伸縮性列表</b></p><p> for(int i=0; i<count; i++) {</p><p> provinceList.collapseGroup(i);</p><p><b> }</b></p>&
89、lt;p><b> }</b></p><p> 如上所述則就實現(xiàn)了帶有過濾性可伸展性列表適配性的實現(xiàn),則在使用時在</p><p> XML 組件配置文件中使用 ExpandableListView 列表,并調用它的 setAdapter()方</p><p> 法來,加載自定義的適配器。而在使用它的過濾功能時則調用自定義適配器
90、的</p><p> getFilter()得到過濾 Filter 對象,再調用 Filter 對象的 filter(String)方法實現(xiàn)的,在</p><p> 本系統(tǒng)中才用的時觸發(fā)文本輸入框 EditText 的 TextChangedListener 事件時調用從而實現(xiàn)手動選擇預報城市的過濾查詢。</p><p><b> 14</b&
91、gt;</p><p> 3.GPS 定位功能的實現(xiàn)</p><p> Android 中調用 GPS 功能,首先要獲取 GPS 定位管理器 LocationManager,獲取 LocationManager 后就是獲取 LocationProvider,可以通過 Criteria 對象設置過濾條件來獲得最符合用戶需求的 LocationProvider,得到 LocationPro
92、vider 后就可通過調用 LocationMananger 對象的 getLastKnownLocation() 方法來獲取 Location 地址封裝對象,最后由實例化的 Geocoder 將 Location 中的經(jīng)度和緯度反編譯為地址信息集合 List 對象,從而由 List 對象來得到當前用戶地址名。在開發(fā)過程中通過 Eclipse 中的 ADT 插件的 DDMS 可以為 Android 模擬器指定任意地址,如下:</p
93、><p> 當在模擬器控制面板中指定經(jīng)緯度后,則會在模擬器中出現(xiàn) GPS 的標志:</p><p> 但在實際開發(fā)調用 GPS 功能過程時,只能獲取經(jīng)度與緯度,而在使用 Geocoder 反編譯地址時報錯:</p><p> 使用的調用代碼如下:</p><p> 后來通過網(wǎng)上搜索得知在 Android2.2 模擬器中調用 Geocode
94、r 需要 backend 服務: ”The Geocoder class requires a backend service that is not included in the core android framework. The Geocoder query methods will return an empty list if there no backend service in the platform.“</p
95、><p><b> 15</b></p><p> 但并有說此服務要怎么得到,這看起來像是 Android2.2 模擬器的一個 Bug,故而在本設計中采用訪問[http://maps.google.cn/maps/geo?output=xml&q=經(jīng)度,緯度]的形式來得到詳備的地址信息(來源于:http://www.iteye.com/problems/695
96、17),如下訪問 http://maps.google.cn/maps/geo?output=xml&q=30.659269,104.065762:</p><p> 其中的 output 參數(shù)指定的是服務器響應的格式,除了 XML 格式還可以為 JSON, CSV 等格式。</p><p> 由此可知,為了實現(xiàn) GPS 的定位功能還需要實現(xiàn)一個解析 XML 的工具類,在本&l
97、t;/p><p> 系統(tǒng)中由工具類 LocationXMParser 完成,它繼承至 org.xml.sax.helpers.DefaultHandler</p><p> 類,用于專門用于解析 XML 文件。</p><p> 上述的 GPS 功能具體實現(xiàn)過程如下:</p><p> 1.得到 LocationManager 系統(tǒng)定位
98、服務管理者:</p><p> LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);</p><p><b> 16</b></p><p> 設置 Geocoder 對象,過濾得到符合條件的 Locat
99、ionProvider ,再由 LocationProvider 得到封裝經(jīng)緯度信息的 Location 對象:</p><p> //設置一個Criteria標準用于過濾LocationProvider</p><p> Criteria criteria = new Criteria();</p><p> //設置不需要高度信息</p>&
100、lt;p> criteria.setAltitudeRequired(false);</p><p> //設置不需要方位信息</p><p> criteria.setBearingRequired(false);</p><p> //得到最好的可用的Provider</p><p> String provider =
101、locationManager.getBestProvider(criteria, true); //得到當前的位置對象</p><p> Location location = locationManager.getLastKnownLocation(provider); double latitude = location.getLatitude(); //得到經(jīng)度</p><p>
102、 double longitude = location.getLongitude(); //得到緯度</p><p> 得到經(jīng)緯度后再訪問 http://maps.google.cn/maps/geo 來得到含地址信息的</p><p> XML 文本內容,并用自定義的 LocationXMParser 工具類解析封裝得到此經(jīng)緯度對應的城市名:</p><p&g
103、t; //根據(jù)經(jīng)緯度得到詳細的地址信息</p><p> //定義的一個網(wǎng)絡訪問工具類</p><p> WebAccessTools webTools = new WebAccessTools(this); String addressContext = webTools.getWebContent</p><p> ("http://maps.
104、google.cn/maps/geo?output=xml&q="+ latitude+","+longitude);</p><p><b> //解析地址信息</b></p><p> SAXParserFactory spf = SAXParserFactory.newInstance(); try {</p>
105、;<p> SAXParser parser = spf.newSAXParser(); XMLReader reader = parser.getXMLReader(); LocationXMLParser handler = new LocationXMLParser(); reader.setContentHandler(handler);</p><p> StringReader re
106、ad = new StringReader(addressContext);</p><p> 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入</p><p> InputSource source = new InputSource(read);</p><p><b> //開始解析</b>
107、;</p><p> reader.parse(source);</p><p> //判斷是否存在地址</p><p> if(handler.hasAddress())</p><p> return handler.getDetailAddress(); } catch (Exception e) {</p>&l
108、t;p> e.printStackTrace();</p><p><b> }</b></p><p><b> 17</b></p><p> 上面代碼中的 getDetailAdress()方法返回的是一個 Map 對象,其中封裝了從 XML 中解析得到的國家、省份、縣區(qū)和城市四個信息,在得到這些信息后
109、,系統(tǒng)將與數(shù)據(jù)庫中預存的省份城市相比較,最終匹配得到該地區(qū)的城市碼完成 GPS 自動定位功能的實現(xiàn)。</p><p> 4.Widget 窗體小部件的更新</p><p> 由于 widget 中的時鐘關系,需要對 widget 顯示進行時刻的更新用來保持與系統(tǒng)中時間的一致。實現(xiàn)這個功能需要用到 AlarmManager 類,這個類專門用來設定在某個指定的時間去完成指定的事件。設計思路
110、是在 Widget 的 onUpdate 方法中啟動一個自定義更新后臺服務,更新 widget,并設定下一分鐘再次調用此服務。具體實現(xiàn)過步驟如下:</p><p> 首先自定義一個后臺運行服務類繼承至 Service 類,實現(xiàn)它的服務開始運行調用的 onStart()方法:</p><p> super.onStart(intent, startId);</p><
111、p> //得到widget的布局對象</p><p> RemoteViews views = WeatherWidget.getWeatherView(this); //得到AppWidgetManager widget管理器</p><p> AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(thi
112、s); int[] appids=appWidgetManager.getAppWidgetIds(new ComponentName(this,</p><p> WeatherWidget.class));</p><p> //得到城市碼,并更新天氣</p><p> SharedPreferences sp=getSharedPreferences(&
113、lt;/p><p> SetCityActivity.CITY_CODE_FILE,</p><p> SetCityActivity.MODE_PRIVATE);</p><p> String cityCode= sp.getString("code", "");</p><p> if(cit
114、yCode!=null&&cityCode.trim().length() > 0) { WeatherWidget.updateAppWidget(views, this,</p><p> appWidgetManager, cityCode);</p><p><b> }</b></p><p> appWi
115、dgetManager.updateAppWidget(appids, views); //獲取當前時間設置警報服務</p><p> Date date = new Date();</p><p> long now =date.getTime();</p><p> long unit=60000;//間隔一分鐘</p><p>
116、 int s=date.getSeconds();//得到秒數(shù)</p><p> unit=60000-s*1000;//將時間精確到秒</p><p> pintent=PendingIntent.getService(this, 0, intent, 0);</p><p><b> //計時器</b></p>&l
117、t;p> alarm=(AlarmManager)getSystemService(Context.ALARM_SERVICE);</p><p> //AlarmManager.RTC_WAKEUP設置服務在系統(tǒng)休眠時同樣會運行</p><p> //第二個參數(shù)是下一次啟動service時間</p><p> alarm.set(AlarmManag
118、er.RTC_WAKEUP, now+unit, pintent);</p><p><b> 18</b></p><p> 然后在實現(xiàn) AppWidgetProvider 的 widget 類的 onUpdate 方法中啟動這個自定義的服務:</p><p> //啟動一個自定義更新widget的后臺服務</p><
119、;p> context.startService(new Intent(context,UpdateWidgetService.class));</p><p> 除了啟動這個服務是不夠的,當用戶刪除 widget 部件時,后臺服務也必須停止,這樣就必須實現(xiàn) Service 類中的另一個方法 onDestroy()方法,該方法在 Service 停止時調用,在這里用于取消 AlarmManager 設置
120、的警報服務:</p><p> //當widget中通過調用context.stopService方法來指定銷毀service時,被調用 public void onDestroy() {</p><p><b> //取消定時管理</b></p><p> if( alarm!=null) {</p><p>
121、 alarm.cancel(pintent);</p><p><b> }</b></p><p> super.onDestroy();</p><p><b> }</b></p><p> 則在 widget 類的 onDisabled()方法中調用 stopService 方法來停
122、止后臺服務,</p><p> 其中的 onDisabled 方法在 widget 被用戶刪除時由系統(tǒng)自動調用:</p><p> public void onDisabled(Context context) { super.onDisabled(context);</p><p><b> //關閉后臺服務</b></p>
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 手機天氣預報系統(tǒng)畢業(yè)論文
- 畢業(yè)論文——手機天氣預報系統(tǒng)畢業(yè)設計
- 畢業(yè)論文——手機天氣預報系統(tǒng)畢業(yè)設計
- android3g手機天氣預報系統(tǒng)-畢業(yè)論文
- 手機天氣預報系統(tǒng)
- 手機天氣預報系統(tǒng)畢業(yè)設計.pdf
- 手機天氣預報系統(tǒng)畢業(yè)設計.pdf
- 基于android手機天氣預報系統(tǒng)
- 基于android手機移動天氣預報系統(tǒng)
- 基于android系統(tǒng)天氣預報應用程序畢業(yè)論文
- 基于Android手機的天氣預報查詢系統(tǒng).pdf
- 基于遠程調用數(shù)據(jù)的天氣預報系---畢業(yè)論文
- 基于android平臺的天氣預報系統(tǒng)的設計與開發(fā)畢業(yè)論文
- android平臺天氣預報軟件設計與實現(xiàn) 畢業(yè)論文
- android平臺天氣預報widget的設計與實現(xiàn)畢業(yè)論文
- android平臺天氣預報widget的設計與實現(xiàn)畢業(yè)論文
- 短期天氣預報試題庫天氣預報概要
- 專題天氣預報
- 農(nóng)用天氣預報
- 《天氣預報》教案
評論
0/150
提交評論