手机天气预报系统毕业设计_第1页
手机天气预报系统毕业设计_第2页
手机天气预报系统毕业设计_第3页
手机天气预报系统毕业设计_第4页
手机天气预报系统毕业设计_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目录需求分 88888888888888888888888888888888888888888888888888..二L项目.需求分•.…总体•设8888888888888..二L项目.需求分•.…总体•设8888888888888计一8、88系统规88^^88^^88划L系统功能界…•••••••••M«•2,888.2,88设置预报城市界型•天气显示界 3 面:Widget桌面小部件界 888888 4三面设计目 系统设8888888888885 计一、88开发及•运行环^888888888^8^8:-88境.88数据库.设 6 三^:主要方法及步 S 四、主要方法及技::::::::::::::::::::::::::.6 主要模88888888888888888888888888888.7 888.7,块一、:8项目•木匡:::::88:::::::::::::::::888:8^888.7,::架i::主要功能实 :::: :::::: 项 78888888888888888888888888888888888888888888888如1:获取城市•码:db项泌比如8:曲:数据库文 ::件 8件实现可伸缩性列表的的构建与过 滤GPS定位功能的实 现widget窗体小部件的更功能新J8888888888888888888试::8:8:8::88-18 论.8论.8 23摘要Window操作系统的诞生成就了微软帝国,同时也造就7PC时代的繁荣,然而如今,以Android和iPhone手机为代表的智能移动设备的发明与互联网云技术的兴起却敲响了PC时代的丧钟!这也预示着移动互联网时代(3G)已经来临。在这个互联网繁荣的时代,有一颗超新星,以它独特性能优势与人性化的UI设计使它在短短的几年迅速的占领了智能移动设备的市场份额,它就是Google的Android!这也意味着Google在移动互联网时代开始抢跑并领跑。Android是基于Linux平台完全开源的手机操作系统,同时开发语言为Java,这对于Java开发的我们是何等的诱人,程序员的技术要与时代同行,因此我选择了以Android为平台的手机天气预报系统来作为我的毕业设计,选择手机天气预报系统不仅可以提升技术,同时也很实用,为人们时刻了解天气状况和出行带来了方便。需求分析一、 开发背景近几年来随着3G技术成熟和智能手机的不断普及,移动应用的需求与日俱增,移动应用开发成为当下最热门的技术之一。在Google和Android手机联盟的共同推动下,Android在众多移动应用开发平台中脱颖而出。Android是一个真正意义上的开源智能手机操作系统,该系统一经推出立即受到全球移动设备厂商和开发者的热捧。为顺应潮流,本设计旨在搭载Android的移动设备上运行,实现天气状况的实时动态更新与显示,方便人们的出行与生活。二、 项目需求分析根据功能的需求,分析此项目的主要功能应具备以下几点:精确查询定位全国各地城市未来几天内的实时天气状况系统要具的实用性,符合用户查看信息习惯,界面设计优美系统要具有稳定性,且在一定程度上节省流量的开销总体设计一、系统规划由上述的需求,现将系统分为三大模块:天气显示界面模块、预报城市设置模块与Widget桌面小部件模块。各系统模块功能如下:.天气显示界面模块显示指定城市三天内的天气状况,包括日期、城市名称、温度、风力与当日的建议,用户可通过按菜单键来显示菜单更新当前天气与设置天气显示的界面背景,以及跳转至设置预报城市界面来更换预报城市。.预报城市设置模块由自动设置预报城市与手动设置二部分组成,自动设置实现GPS定位功能,自动确定当前用户所在地;而手动设置则通过可伸展性下拉列表单击选择系统数据库中预存的城市来进行设置,同时为了方便用户查找,支持以输入框的形式来过滤查询预报城市。当单击选中城市时跳转至天气显示界面,来显示该城市当三天内的天气状况;第一次运行时自动跳到该界面。.Widget桌面小部件模块为了方便用户实时了解天气状况,特别添加在Android系统桌面上显示当前天气与时间的天气小部件,使用户拿起手机的第一时刻就能了解天气,同时当用户单击小部件时,自动跳转至天气显示界面,显示三天内的详细天气。

二、系统功能界面设置预报城市界面:1.1当第一次运行程序时,跳转至城市设置界面进行预报城市的选择:1.2用户可以通过单击选择“定位当前城市”的方式调用系统GPS功能自动定位预报城市:

1.3用户可通过输入框过滤查询当前系统中预存的城市:天气显示界面:2.1选择了预报城市后,系统跳转至天气显示界面,显示该城市三天内的实时天气:乏01?年12月W7日(星期二) 辛卯年武汉 整

2.2在天气界面中用户可通过按菜单键来调出菜单,选择城市,更新天气与更换背景:Widget桌面小部件界面:方便用户第一时间了解天气动态,添加widget显示功能界面:

设计目标设计完成一个实用稳定的天气预报系统,同时要廉价使其能满足大部分用户的需求,因此针对上述要求,本设计应满足:系统能及时的返反馈指定预报城市的天气情况自动定位用户所在城市,支持GPS定位节省流量开销,规定在指定的时间间隔内才更新天气,其它时段显示缓存的天气操作方便快捷,使用简单,界面设计美观大方,支持widget系统设计、开发及运行环境JDK1.6.10Eclipse3.5AndroidDevelopmentToolkit(ADT)15.0.0Android2.2及以上WindowsXP及以上二、数据库设计由于在本系统中是通过中央气象台的WebService提供的API访问得到的天气预报,在查询指定城市的天气时,需要用到它提供的城市码,而城市码相对稳定不变,所以在构建系统时将其事先通过Android的网络访问技术将其缓冲到本地SQLite数据库进行保存起来,方便以后的查询,同时节省了流量开销。综上所述在本地建立db_weather.db的数据库,其中的表结构如下:provinces,idIN7ZJUt/stprovinces,idIN7Oprovince_dINTiiameTECT。匚i1y_iiLimTEXT其中只存在两个表:provices和citysCity中存在city_num用天气的查询,同时还存在外键province_id与provices表形成1对n的关系。三、 主要方法及步骤搭建Android开发环境,并建立一个android2.2版本名为WeatherSystem项目首先编写网络访问代码,访问/data5/city.xml中央气象站解析得到所有城市码并导出保存得到的db_weather.db数据文件在程序第一次运行时,将db_weatcher.db数据库文件导入到应用程序数据库中建立设置城市界面,读取数据库文件,获取省份,城市以及对应的城市码。接收用户选择的城市码,访问:/data/<城市码>.html得到天气信息解析天气信息,将城市码及天气信息缓冲下来,并为其设置有效时间,方便下次启动时直接得到天气信息,过期则从网上更新定时由保存的城市码更新天气信息四、 主要方法及技术Android手机的界面UI设计Android的网络通信Android的广播GPS调用解析Widget小部件编程XML与JSON解析SQLite数据库操作Android文件操作主要模块一、项目框架在装有ADT插件的Eclipse中新建一个名为WeatherSystem的Android2.2版本的项目,项目主要文件结构如下:WeatherSystemsrc|_com.weather.app| |_MainActivity.java| |_SetCityActivity.java| |_UpdateWidgetService.java| |_WeatherWidget.java||_p| |_GPSListAdapter.java| |_MyListAdpater.java||_com.weather.dao| |_DBHelper.javacom.weaher.utils

_LocationXMParser.java|_WeatherInfoParser.java|_WebAccessTools.java—res|_drawable| |_(略)|_layout||_gps.xml||_main.xml||_widget_layout.xml||_set_city.xml||_menu| ||_configure_menu.xml||_raw||_db_weather.db||_values||_color.xml||_strings.xml||_xml|_weather_widget.xml|_AndroidManifest.xml二、主要功能实现获取城市码db_weather.db数据库文件获取全国各地的城市码,是通过访问中央气象局网从省份直辖市到城镇一级一级深入得到的,获得一个地区的城市码总共需要访问4次网络,分别如下:访问/data5/city.xml得到省份直辖市列表与它的编号:01|北京,02|上海,03|天津,04|重庆,05|黑龙江,06|吉林,07|辽宁,08|内蒙古,…访问/data5/city<省份编号>.xml得到该省份直辖市的城市编号(如访问山东:/data5/city12.xml)1201|济南,1202|青岛,1203|淄博,12041德州,1205|烟台,1206|潍、、坊, 、、 、、、访问/data5/city<城市编号>.xml得到该城市的县区编号(如访问济南:/data5/city1201.xml)120101|济南,120102|长清,120103|商河,120104|章丘,120105|平阴,….访问/data5/city〈县区编号>.xml得到该县区的城市码(如访问长清:http://m.weather./data5/city120102.xml)120102101120102120102101120102首先实现上述功能需使用Android的网络访问技术,故编写工具类WebAccessTools类如下:/***根据给定的url地址访问网络,得到响应内容(这里为GET方式访问)@paramurl指定的url地址©returnweb服务器响应的内容,为<code>String</code>类型,当访问失败时,返回为null*/publicStringgetWebContent(Stringurl)(//创建一个http请求对象HttpGetrequest=newHttpGet(url);//创建HttpParams以用来设置HTTP参数HttpParamsparams二newBasicHttpParams();//设置连接超时或响应超时HttpConnectionParams.setConnectionTimeout(params,3000);HttpConnectionParams.setSoTimeout(params,5000);//创建一个网络访问处理对象HttpClienthttpClient=newDefaultHttpClient(params);try(//执行请求参数项HttpResponseresponse=httpClient.execute(request);〃判断是否请求成功if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK)(//获得响应信息Stringcontent=EntityUtils.toString(response.getEntity());returncontent;}else(//网连接失败,使用Toast显示提示信息Toast.makeText(context,〃网络访问失败,请检查您机器的联网设备!",Toast.LENGTH_LONG).show();}}catch(Exceptione)(e.printStackTrace();}finally(〃释放网络连接资源httpClient.getConnectionManager().shutdown();}returnnull;}由上面访问的可知,得到的编码与名称都是“编码I名称”的形式,因此在这也编写一个解析得到城市码的工具类WeatherInfoParser,用于解析从服务器中得到的城市码:/***通过解析content,得到一个一维为城市编号,二维为城市名的二维数组*解析的字符串的形式为:<code>编号|城市名,编号|城市名,.....</code>@paramcontent需要解析的字符串©return封装有城市编码与名称的二维数组*/publicstaticString口口parseCity(Stringcontent)(//判断content不为空if(content!二null&&content.trim().length()!=0)(StringTokenizerst=newStringTokenizer(content,〃,〃);intcount=st.countTokens();String口口citys=newString[count][2];inti=0,index=0;while(st.hasMoreTokens())(Stringcity=st.nextToken();index=city.indexOf('l');citys[i][0]=city.substring(0,index);citys[i][1]=city.substring(index+1);i=i+1;}returncitys;}returnnull;}编写这两个类后现在就是编写从服务器端用程序遍历得到全国各地的城市名与城市码,并将它们分别的保存在String口口provinces数组,String口口childs数组与String口口cityCode中:WebAccessToolswebTools=newWebAccessTools(this);//得到访问网络的内容StringwebContent二webTools.getWebContent(〃/data5/city.xml〃);〃第一次解析得到的为省份或一级直辖市String口口provinces=WeaterlnfoParser.parseCity(webContent);String[]groups=newString[provinces.length];String口口childs=newString[provinces.length][];String口口cityCode=newString[provinces.length][];for(inti=0;i<provinces.length;i++)(groups[i]=provinces[i][1];〃由省份码来得到城市码StringBufferurlBuilder=newStringBuffer(〃/data5/city〃);urlBuilder.append(provinces[i][0]);urlBuilder.append(〃.xml〃);webContent=webTools.getWebContent(urlBuilder.toString());String口口citys=WeaterlnfoParser.parseCity(webContent);//用于保存所的有townsString□口口towns=newString[citys.length]口口;〃计算总的城镇数intsum=0;for(intj=0;j<citys.length;j++)(〃由城市码来得到地方码urlBuilder二newStringBuffer(〃/data5/city〃);urlBuilder.append(citys[j][0]);urlBuilder.append(〃.xml〃);webContent=webTools.getWebContent(urlBuilder.toString());towns[j]=WeaterInfoParser.parseCity(webContent);sum=sum+towns[j].length;}childs[i]=newString[sum];cityCode[i]=newString[sum];sum=0;for(intj=0;j<citys.length;j++)(for(intn=0;n<towns[j].length;n++)(if(n==0)childs[i][sum]=towns[j][n][1];elsechilds[i][sum]=towns[j][0][1]+〃.〃+towns[j][n][1];urlBuilder二newStringBuffer(〃/data5/city〃);urlBuilder.append(towns[j][n][0]);urlBuilder.append(〃.xml〃);webContent=webTools.getWebContent(urlBuilder.toString());String口口code二WeaterlnfoParser.parseCity(webContent);cityCode[i][sum]=code[0][1];sum=sum+1;}}urlBuilder二null;}接下来就是将得到的上面的三个数组建立数据库文件db_weather.db保存起来,用到android.database.sqlite.SQLiteDatabase类的静态方法:SQLiteDatabaseopenOrCreateDatabase(Stringpath,CursorFactoryfactory)来创建一个数据库文件,其中的path表示数据库存放的路径,而factory中游标工厂,这里可将它设为空,从而得到SQLiteDatabase对象,则再调用它的execSQL(Stringsql)方法来执行保存数据库的操作,从而将上面的三个数组转换为数据库中的数据,最后使用ADT插件中的DDMS工具将得到的数据库文件从Android模拟器中导出,最终就得到了db_weather.db文件。以后上述的代码就可以不使用,直接将db_weather.db文件放入资源文件夹res目录中的raw目录中,则在程序第一次运行时导入到/data/data/com.weather.app/databases目录中就行了,其中关于数据库的导入实际是Java中文件的复制。实现可伸缩性列表的的构建与过滤实现可伸缩性列表是通过继承android.widget.BaseExpandableListAdapter适配器实现的,其中主要实现它的publicViewgetGroupView()得列表的一级列表和publicvoidgetChildView()得到列表的二级子列表实现的,在这里由于只是实现文本显示功能,故用TextView组件来填充就行了,如果要构造这个自定义的适配器,则只需在提供存放省份直辖市的一级列表的数组String口groups和存放对应的城镇的二级列表的String口口childs就行了。同时为了兼具过滤功能,还要需再实现android.widget.Filterable接口,这个接口有一个getFilter()返回Filter过滤器的列表,故还要提供一个Filter过滤类,在本系统中,实现的是一个内部类CityFilter,它继承android.widget.Filter类,覆盖实现了两个方法,一个是performFiltering()得到FilterResults过滤结果对象方法,另一个是根据得到的FilterResults对象更新适配器的publishResults()方法。其中的performFiltering(CharSequenceconstraint)方法的实现是通过constraint这个关键字以省份直辖市为单位进行匹配,如果匹配成功,则添加该省份以下的所有城市,如果匹配不成功,则再逐一与这个省份的下的城市配匹,则只添加匹配的城市,其中匹配的结果放在Map<Integer,ArrayList<Integer>>values这样的向量中,再由新建的FilterResults封装返回,(具体实现如下):首先是对关键字进行判断是否为空,如为空则由values添加所有省份与城

市,其中的allGroups和allChilds保存的是所有的省份与对应的城市:〃当过滤条件为空时,返回所有的省份与城市if(constraint==null||constraint.length()==0)(for(inti=0;i<allGroups.length;i++)(ArrayList<Integer>index=newArrayList<Integer>();〃添加所有与之对应的城市for(intj=0;j<allChilds[i].length;j++)(index.add(j);}values.put(i,index);}}如果关键字constraint不为空,则以省份为单位进行匹配,省份匹配的添加下面的所在城镇,如果不匹配,则进行步深入匹配城镇,添加符合条件的城镇:StringfilterStr=constraint.toString();for(inti=0;i<allGroups.length;i++)(〃查找省名是否包含用户输入的字符串if(allGroups[i].contains(filterStr))(ArrayList<Integer>index=newArrayList<Integer>();〃添加所有与之对应的城市for(intj=0;j<allChilds[i].length;j++)(index.add(j);}values.put(i,index);}else(ArrayList<Integer>index=newArrayList<Integer>();〃如果省份名没有,则查找它下面的城市名是否包含for(intj=0;j<allChilds[i].length;j++)(if(allChilds[i][j].contains(filterStr))(index.add(j);}}〃如果添加进入了城市,说明存在,则它的省份也添加进去if(index.size()>0)(values.put(i,index);}else(index=null;}}}得到过滤的结果后将其用FilterResource封装后返回:FilterResultsresults=newFilterResults();results.values=values;results.count=values.size();另夕卜的publishResults(CharSequenceconstraint, FilterResultsresults)方法就是根据上面得到的results对象来得到新的String]]groups与String口口Childs数组,再调用BaseExpandableListAdapter父类的notifyDataSetChanged()方法来更新列表,从而实现过滤后结果的显示(具体实现如下):首先将参数FiltersResuls对象转换为Map<Integer,ArrayList<Integer>>filterResult,然后来判断过滤后的结果长度时否为0,如果长度为0则说明过滤后的结果为空,则调用父类的notifyDataSetInvalidated()方法来阻止列表的更新:如果长度不为0,则说明存在过滤结果,则将它转换为groups数组与childs数组,并调用notifyDataSetChanged()方法实再更新:String]]newGroups=newString[count];String口口newChilds=newString[count]口;intindex=0;intlength=0;//得到新的groups和childsfor(inti=0;i<allGroups.length;i++)(if(filterResult.containsKey(i))(newGroups[index]=allGroups[i];〃符合条件的城市ArrayList<Integer>citys=filterResult.get(i);length=citys.size();newChilds[index]=newString[length];for(intj=0;j<length;j++)(newChilds[index][j]=allChilds[i][citys.get(j)];}index=index+1;}}//设置groups和childsgroups=newGroups;childs=newChilds;〃更新列表notifyDataSetChanged();〃判断是否展开列表count=getGroupCount();if(count<34)(//展开伸缩性列表for(inti=0;i<count;i++)(provinceList.expandGroup(i);}}else(//收缩伸缩性列表for(inti=0;i<count;i++)(provinceList.collapseGroup(i);}}如上所述则就实现了带有过滤性可伸展性列表适配性的实现,则在使用时在XML组件配置文件中使用ExpandableListView列表,并调用它的setAdapter()方法来,加载自定义的适配器。而在使用它的过滤功能时则调用自定义适配器的getFilter()得到过滤Filter对象,再调用Filter对象的filter(String)方法实现的,在本系统中才用的时触发文本输入框EditText的TextChangedListener事件时调用从而实现手动选择预报城市的过滤查询。GPS定位功能的实现Android中调用GPS功能,首先要获取GPS定位管理器LocationManager,获取LocationManager后就是获取LocationProvider,可以通过Criteria对象设置过滤条件来获得最符合用户需求的LocationProvider,得到LocationProvider后就可通过调用LocationMananger对象的getLastKnownLocation()方法来获取Location地址封装对象,最后由实例化的Geocoder将Location中的经度和纬度反编译为地址信息集合List对象,从而由List对象来得到当前用户地址名。在开发过程中通过Eclipse中的ADT插件的DDMS可以为Android模拟器指定任意地址,如下:LeedtionCentreIsManualGPX|KML■硕Decimal.SexagesimalLongitude104.0665762Latitude30.659269Send当在模拟器控制面板中指定经纬度后,则会在模拟器中出现GPS的标志:但在实际开发调用GPS功能过程时,只能获取经度与纬度,而在使用Geocoder反编译地址时报错:Sys-em.-Erriava.in.ICEitcep-iari:Servicen.a'"AvailableSYS^iL.erEandcoid.laca^ian.'jsocadee.gsyr-jnLL-jea('jEoc<jdeE.javd:117)Syszeia.-Errcom.weather.Hpp.SetCiLy^cTivi7y.geTl.acaT.LonCizylk]ne(SetCityActwity.i...SyszeiL.erra?can.we己th己r.spp.SetCiLykct onl lick(SetCilyActivi?y.javi:S2)使用的调用代码如下:侦==newcoder(thisf ;E■:〃捋经纬度转换成地址的信息「最后的】表示最大充许的结果数LiBt<Addr&BB>addresseB=gc.gerFromLncarinn(larirude,Inngirude,1};lf((]>0]Addressaddress=addresses.e'er.(3];返回定位的城市地址塔if(address・ = = (j>0)re-urn (0];J':□□.Lcn( 己)=•.pr^nt.3t.aiskTrace(];后来通过网上搜索得知在Android2.2模拟器中调用Geocoder需要backend服务:”TheGeocoderclassrequiresabackendservicethatisnotincludedinthecoreandroidframework.TheGeocoderquerymethodswillreturnanemptylistiftherenobackendserviceintheplatform.“但并有说此服务要怎么得到,这看起来像是Android2.2模拟器的一个Bug,故而在本设计中采用访问[/maps/geo?output=xml&q二经度,纬度]的形式来得到详备的地址信息(来源于:/problems/69517),如下访问/maps/geo?output=xml&q=30.659269,104.065762:-<LubI>—<Respoose>cname>30.659269:104.065'"62<-<Status><code>20Q<ccde><request>geocode<request><Status>-<Phcemarkid—'pl'^<address>i=h@四J11省成都市青羊区四川科技馆南门<address>—<\ddressDetailsAccuracy='9>-<Couutn^><CounmNameCade>CN<CounrnNameCade>V fa<Countr^Name>§<Counam&>-<ldmLQL5tratiY^Area><\dmiDistrativeAreaXame>E3JI®AdmiDistrativexALreaNa>-<Tocalitx>V<LocalinXamQ成都市<Loc^liuName>一<Depeud^utLocaLi^-><Depend叩tLocalihName>青羊区VDependentLocalit>Xame>—<Tborou^hfare>cThorougLfareName>四川科技馆南口<LTLorouffhfareName><Thoroughfare><AddressLlae>四川科技馆南门AddressLioe><DependentLocalit>><.'LocalLrL><AdministrafiveArea><-Countt7_><AddressDetails>—<EitetidedData><LatLoDBox曲汕='也.部腔919"soutb=l30.6490552"eas^"104.0822464"wes^'l04.0502316"><TxtendedData>-<PoLdt><coordiDates>104.0662390:30.55S^940:0<coordinates><^Placemark><.Respons&><kmL>其中的output参数指定的是服务器响应的格式,除7XML格式还可以为JSON,CSV等格式。由此可知,为了实现GPS的定位功能还需要实现一个解析XML的工具类,在本系统中由工具类LocationXMParser完成,它继承至org.xml.sax.helpers.DefaultHandler类,用于专门用于解WXML文件。上述的GPS功能具体实现过程如下:得到LocationManager系统定位服务管理者:LocationManagerlocationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);设置Geocoder对象,过滤得到符合条件的LocationProvider,再由LocationProvider得到封装经纬度信息的Location对象://设置一个Criteria标准用于过滤LocationProviderCriteriacriteria=newCriteria();//设置不需要高度信息criteria.setAltitudeRequired(false);//设置不需要方位信息criteria.setBearingRequired(false);//得到最好的可用的ProviderStringprovider=locationManager.getBestProvider(criteria,true);//得到当前的位置对象Locationlocation=locationManager.getLastKnownLocation(provider);doublelatitude=location.getLatitude();//得到经度doublelongitude=location.getLongitude();//得到纬度得到经纬度后再访问/maps/geo来得到含地址信息的

XML文本内容,并用自定义的LocationXMParser工具类解析封装得到此经纬度对应的城市名:〃根据经纬度得到详细的地址信息//定义的一个网络访问工具类WebAccessToolswebTools=newWebAccessTools(this);StringaddressContext=webTools.getWebContent("/maps/geofoutput=xml&q=〃+latitude+〃,〃+longitude);//解析地址信息SAXParserFactoryspf=SAXParserFactory.newInstance();try(SAXParserparser=spf.newSAXParser();XMLReaderreader=parser.getXMLReader();LocationXMLParserhandler=newLocationXMLParser();reader.setContentHandler(handler);StringReaderread=newStringReader(addressContext);//创建新的输入源SAX解析器将使用InputSource对象来确定如何读取XML输入InputSourcesource=newInputSource(read);〃开始解析reader.parse(source);〃判断是否存在地址if(handler.hasAddress())returnhandler.getDetailAddress();}catch(Exceptione)(e.printStackTrace();上面代码中的getDetailAdress()方法返回的是一个Map对象,其中封装了从XML中解析得到的国家、省份、县区和城市四个信息,在得到这些信息后,系统将与数据库中预存的省份城市相比较,最终匹配得到该地区的城市码完成GPS自动定位功能的实现。Widget窗体小部件的更新由于widget中的时钟关系,需要对widget显示进行时刻的更新用来保持与系统中时间的一致。实现这个功能需要用到AlarmManager类,这个类专门用来设定在某个指定的时间去完成指定的事件。设计思路是在Widget的onUpdate方法中启动一个自定义更新后台服务,更新widget,并设定下一分钟再次调用此服务。具体实现过步骤如下:首先自定义一个后台运行服务类继承至Service类,实现它的服务开始运行调用的onStart()方法:super.onStart(intent,startId);//得到widget的布局对象RemoteViewsviews=WeatherWidget.getWeatherView(this);//得到AppWidgetManagerwidget管理器AppWidgetManagerappWidgetManager二AppWidgetManager.getInstance(this);int[]appids二appWidgetManager.getAppWidgetIds(newComponentName(this,WeatherWidget.class));〃得到城市码,并更新天气SharedPreferencessp=getSharedPreferences(SetCityActivity.CITY_CODE_FILE,SetCityActivity.MODE_PRIVATE);StringcityCode=sp.getString(〃code〃,"");if(cityCode!二null&&cityCode.trim().length()>0)(WeatherWidget.updateAppWidget(views,this,appWidgetManager,cityCode);}appWidgetManager.updateAppWidget(appids,views);//获取当前时间设置警报服务Datedate=newDate();longnow=date.getTime();longunit=60000;//间隔一分钟ints=date.getSeconds();//得到秒数unit=60000-s*1000; //将时间精确到秒pintent二PendingIntent.getService(this,0,intent,0);//计时器alarm=(AlarmManager)getSystemService(Context.ALARM_SERVICE);//AlarmManager.RTC_WAKEUP设置服务在系统休眠时同样会运行//第二个参数是下一次启动service时间alarm.set(AlarmManager.RTC_WAKEUP,now+unit,pintent);然后在实现AppWidgetProvider的widget类的onUpdate方法中启动这个自定义的服务://启动一个自定义更新widget的后台服务context.startService(newIntent(context,UpdateWidgetService.class));除了启动这个服务是不够的,当用户删除widget部件时,后台服务也必须停止,这样就必须实现Service类中的另一个方法onDestroy()方法,该方法在Service停止时调用,在这里用于取消AlarmManager设置的警报服务://当widget中通过调用context.stopService方法来指定销毁service时,被调用publicvoidonDestroy()(//取消定时管理if(alarm!二null)(alarm.cancel(pintent);}super.onDestroy();}则在widget类的onDisabled()方法中调用stopService方法来停止后台服务,其中的onDisabled方法在widget被用户删除时由系统自动调用:publicvoidonDisabled(Contextcontext)(super.onDisabled(context);〃关闭后台服务context.stopService(newIntent(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论