密级:
学士学位论文
THESISOFBACHELOR
(2007—2011
年)
题目:基于Android平台的3G气象软件
学专学院:软件学院系业:号:计算机软件计算机软件
姓名:指导教师:起讫日期:南昌大学
学士学位论文原创性申明
本人郑重申明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。对本文的研究作出重要贡献的个人和集体,均已在文中以明确方式表明。本人完全意识到本申明的法律后果由本人承担。
作者签名:日期:
学位论文版权使用授权书
本学位论文作者完全了解学校有关保留、使用学位论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。本人授权南昌大学可以将本论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。
保密□,在
本学位论文属于
不保密□。
(请在以上相应方框内打“√”)
作者签名:日期:年解密后适用本授权书。
导师签名:日期:
Android平台3G手机气象软件
专业:计算机软件学号:
学生姓名:指导老师:
摘要
随着智能手机的快速普及,智能手机操作系统市场风生水起。为了让智能手机用户能够随时随地查询互联网所提供的服务,一种高效的办法就是将应用系统的功能拓展到手机终端上,让手机能够通过移动网以及互联网访问Web网站并处理各种各样的业务。因此,智能手机的应用软件及其需要的服务将有广阔的发展前景。
在如今这个智能手机系统群雄纷争的时候,2008年Google推出了一款名为Android的开源智能手机操作系统,它采用Linux内核,开放手机联盟(OHA)成员可以任意使用和修改SDK包,系统的开源性使其具有良好的拓展性。这款软件包括了操作系统、用户界面和应用程序,即智能手机工作所需要的全部软件。Android的最大特点是其开放性体系架构,不仅具有非常好的开发、调试环境,而且还支持各种可扩展的用户体验,包括丰富的图形组件、多媒体支持功能以及强大的浏览器。因此,对于软件从业人员来说,Android平台具有无限的吸引力。
本文就在分析讨论Android手机软件开发技术原理的基础上,开发出能为用户提供更好的基于Android平台的3G手机气象软件。
关键字:android;气象软件;智能手机平台
Abstract
Withtherapidproliferationofsmartphones,smartphoneoperatingsystemmarket,windandwater.InorderforsmartphoneuserstochecktheInternetanytime,anywhereservicesprovidedanefficientwaytoexpandthefunctionofthesystemwillbeappliedtothemobilephoneterminal,themobilephonetoInternetaccessviamobilenetworks,andvarietyofWebsitesandprocessbusiness.Therefore,thesmartphoneapplicationsandtheneedfortheservicewillhavebroadprospectsfordevelopment.
Intoday'ssmartphonesystemwhendisputeswarlords,2008,GoogleintroducedasmartphonecalledtheAndroidopensourceoperatingsystem,whichusesLinuxkernel,OpenHandsetAlliance(OHA)memberscanbefreetouseandmodifytheSDKpackage,thesystemIthasagoodopen-sourcenatureoftheexpansionof.Thesoftwareincludestheoperatingsystem,userinterfaceandapplicationsthatneedtoworksmartphonesallthesoftware.Android'sbiggestfeatureisitsopenarchitecture,notonlyhasaverygooddevelopmentanddebuggingenvironment,butalsosupportsavarietyofscalableuserexperience,includingrichgraphicalcomponents,multimediasupport,andpowerfulbrowser.Therefore,forsoftwareprofessionalsis,Androidplatformhasunlimitedappeal.
Inthispaper,theanalysisanddiscussionAndroidmobilephonesoftwaredevelopmenttechnologyonthebasisoftheprinciple,developedtoprovideuserswithbetterplatformtothe3GhandsetsbasedonAndroidmeteorologicalsoftware.Keywords:android;weathersoftware;smartphoneplatform
目录
摘要............................................................................................................................IAbstract..........................................................................................................................II
第一章绪论....................................................................................................................1
1.1研究内容.......................................................................................................1
1.2研究意义.......................................................................................................11.3研究现状和发展趋势...................................................................................1
第二章系统分析........................................................................................................3
2.1研究目标..........................................................................................................3
2.2需求分析..........................................................................................................3
2.3性能分析..........................................................................................................3
第三章系统开发环境及相关技术..............................................................................4
3.1Android开发环境介绍...................................................................................4
3.2
4.1
4.2
4.3
5.1
5.2
5.3Android开发平台搭建.................................................................................4用户界面设计................................................................................................6数据库设计....................................................................................................6程序模块设计................................................................................................7文件结构与用途............................................................................................9数据提供者..................................................................................................10后台服务......................................................................................................16
5.3.1
5.3.2
5.3.3
5.4
5.4.1
5.4.2获取天气数据....................................................................................16读取天气数据实例............................................................................19定时更新时间。................................................................................19程序入口类ForecastWidget..............................................................19设置页面ConfigureActivity..............................................................21第四章程序设计..........................................................................................................6第五章程序开发............................................................................................................9用户界面......................................................................................................19
5.4.3详细页面DetailForecastActivity........................................................22
5.5动态特效........................................................................................................23
第六章系统测试......................................................................................................25
第七章总结..................................................................................................................29
参考文献......................................................................................................................30致谢..........................................................................................................................31
第一章绪论
1.1研究内容
Android平台3G手机气象软件是基于Android手机平台,运用Java语言,从Google上获取天气预报信息,开发出针对使用Android平台的手机天气预报系统。
1.2研究意义
Android平台3G手机气象软件的开发可以进一步扩大气象信息的覆盖面,让广大公众能够在第一时间方便且快捷地获取最新的气象预报(预警)信息,以便提前预防,把气象灾害造成的损失降到最低。同时也可以强化气象公共服务的职能,完善公共服务体系、改善公共服务手段、增加公共服务产品、提高公共服务质量,更好地发挥了气象事业对经济社会发展的现实性作用。
1.3研究现状和发展趋势
据Gartner最新数据显示,2010年第二、三季度全球智能手机销售继续大幅增长,其中第三季度安卓占全球智能手机市场的25.5%,仅次于塞班,成为第二大智能手机系统。2010第二、三季度与去年同期相比,增度分别是15.4%及22%,增势迅猛。而塞班系统较09年的市场份额,尽管终端销量有大幅度提升,但增势下滑
10%,形势非常严峻。其他操作系统的表现则要平稳很多。
安卓是首款开源代码的操作系统,采用Linux内核,开放手机联盟(OHA)成员可以任意使用和修改安卓的SDK软件包。系统的开源性使其具有良好的拓展性,一方面,为众多移动应用开发者提供了良好的系统性平台,有利于移动应用的集合;另一方面,终端厂商可以针对自身的特殊需要“定制化开发”。与此相比,尽管2010年2月,塞班基本完成开源工作,但由于代码臃肿,用户界面设计缺失,塞班的开源并无实际意义,错失发展良机。
据Informa预测,2012年,安卓手机销量将超过诺基亚塞班手机,届时安卓将成为全球最大的智能手机平台。谷歌表示目前安卓手机每日平均激活量为20万部,销售速度加速上涨。
我们认为,安卓在全球市场的成长壮大,塞班市场份额不断下跌已成不争事实。安卓操作系统发展迅猛主要得益于免费、开源和良好产业运作策略,这三点为安卓在智能手机市场赢得更多的发展机遇。系统的免费让更多的厂商加入,推动了份额的上升;代码的开源让更多的开发者进入应用开发;应用的丰富吸引了更多用户选择,这也是谷歌值得众多厂商学习的地方。此外,谷歌通过OHA联合众多厂商进行系统研发,不断更新版本,将系统应用推广到更多的终端产品中,确保用户体验持续改善。
第一章系统分析
第二章系统分析
2.1研究目标
(1)了解Android应用程序的设计和开发过程;
(2)使用多种组件进行Android平台3G手机气象软件的开发。
本软件是基于Eclipse的开发环境,依托Google气象数据建立气象信息数据库,开发出了针对Android平台的手机天气预报系统。
2.2需求分析
本软件是一个AppWidget应用程序,启动程序后可以进行城市、更新频率的设置,可以通过图片和文字显示当前和未来的天气状况,包括温度、湿度、风向和雨雪情况等。这些天气数据是通过后台服务获取的,这个后台服务可以按照一定时间间隔,从Google上获取天气预报信息,并将天气信息保存在数据库中。
从上面的描述中可以基本了解软件的功能需求:
(1)启动AppWidget应用程序;
(2)设置界面:对要显示天气预报的城市及更新频率进行设置;
(3)显示界面:通过文字和图片显示当前的天气情况,包括日期、时间、城市、
最高温度、最低温度、当前温度等。
(4)详细界面:通过文字图片动画显示当前的天气情况,包括城市当前天气、温
度、风向、风速、湿度;同时显示今后四天的天气情况。
2.3性能分析
程序响应速度快、安全性高、信息处理速度快。
第三章系统开发环境及相关技术
3.1Android开发环境介绍
Android的上层应用程序是用Java语言开发,同时还需要基于Dalvik虚拟机,所以,Google公司推荐使用主流的Java继承开发环境Eclipse。只有Eclipse还不够,因为是使用Java语言进行开发,还应该有由SUN公司提供的JavaSDK(其中包括JRE:JavaRuntimeEnvironment)。此外,Android的应用程序开发和Java开发有较大区别的,所以还需要有Google提供的AndroidSDK。同时,还需要在Eclipse安装ADT,为Android开发提供开发工具的升级或者变更,是Eclipse下开发工具的升级下载的工具。
简言之,需要以下软件,才能搭建Android开发环境,从而进行Android应用程序的开发。(1)JavaSDK(2)Eclipse(3)AndroidSDK(4)ADT3.2
Android开发平台搭建
Android开发平台搭建步骤:
①首先到http://www.eclipse.org/downloads/下载Eclipse集成开发环境并且解压,这里推荐下载JavaEE集成版本,可以为平台的搭建省下不少工作。接着再去http://java.sun.com/javase/downloads/index.jsp站点下载SDK后安装,下载http://dl.google.com/android/android-sdk-windows-1.5_r1.zip,AndroidSDK1.5后解压。第一步下载工序就结束了。
②双击Eclipse解压后目录中的eclipse.exe然后启动,选择Eclipse菜单中的Help->InstallNewSoftware->选项卡上的AvailableSoftware,点击右侧的“Add”输入http://dl-ssl.google.com/android/eclipse/后确定,然后在“Workwith”下拉菜单中选择刚才输入的网址。过一会就会出现一个DeveloperTools选项,勾上以后点击Next以后Eclipse会自动网上查找Android开发工具插件,然后找到AndroidDDMS和AndroidDevelopmentTools,选中这两个点击Finish,Eclipse就会自动下载并安装Android插件了,最后会提示
重启Eclipse。
③重启后选择Eclipse菜单中的Windows->Preferences在左侧的Android项目中SDKLocation中填入AndroidSDK解压后的目录,然后点击Apply。④在WindowsXP的系统变量中的path变量中添加一个值,该值指向解压后的AndroidSDK目录下的tools文件夹。
第四章程序设计
4.1用户界面设计
根据需求分析可以知道,应用程序应包含三个主要的用户界面,这里需要进
一步分析每个用户界面中应该包括哪些显示内容。
在“设置页面”中,需要对要显示天气预报的城市及更新频率进行设置。在“显示页面”中,显示当前的天气状况,包括城市名称、温度、湿度、风向、雨雪情况和获取数据时间等信息。在“详细页面”动态显示当前天气情况,还要显示未来四天的天气情况。
根据对用户界面显示内容的分析,绘制出用户界面的草图,如图4-1
所示。
图4-1用户界面草图
4.2数据库设计
本软件中有两部分数据需要存储,一个是显示页面的数据,另一个详细页
面的数据。因此选择SQLite数据库作为存储数据的方法,建立数据库forcasts.db,并且建立两张表weather_forcastt和weather_widget,分别存储显示页面的数据和详细页面的数据。
表4-1详细页面的数据库表weather_forcast的结构属性_idwidgetIddayOfWeek
low
数据类型integerintegertextinteger
自动增加的主键组件的ID号周几最低温度
说明
highticoncondition
integertexttext
最高温度显示天气的图标未来天气情况
表4-2显示页面的数据库表weather_widget的结构
属性_idcityupdateMilisisConfiguredpostalCodeforecastDateconditiontempFtempChumidityiconwindConditionlastUpdateTime
数据类型integertexttexttexttextintegertextintegerintegertexttexttextinteger
存储Widget组件id进行天气信息查询的城市名
进行天气信息查询的频率,单位为分/次是否设置城市标记预报日期当前天气情况最高温度最低温度当前湿度天气图标风向风速情况最后一次更新时间
说明
4.3程序模块设计
从功能需求上分析可以看出,整个应用程序应划分为4个模块,分别是程
序启动、用户界面、后台服务和数据库适配器,各模块之间的关系如图4-2所示。
从模块结构图中不难看出,后台服务是整个应用程序的核心,主要是“数据获取模块”,负责周期性的从Google获取天气信息。后台服务在程序启动时就由AppWidgetProvider启动,也可由用户界面通过startService()进行启动,启动后的后台服务将一直保持运行状态。
用户界面从数据库中获取天气信息,而没有直接通过网络访问Google的天气数据。之所以这么实际,一方面可以避免因网络通信不畅造成界面失去响应;另一方面,后台服务可以及时更新数据,以保证数据的准确性。
数据库适配器封装了所有对SQLite数据库操作的方法,用户界面和后台服务会调用它来实现数据库操作。
在完成用户界面设计、数据库设计和模块设计后,至此程序设计阶段基本完成。
第五章程序开发
5.1文件结构与用途
在程序开发阶段,首先确定“Android平台3G手机气象软件”的工程名为
ty-weather,据程序模块设计的内容,建立ty-weather工程。Weather工程源代码的结构如图5.1
所示。
图5.1ty-weather工程的源代码文件
为了使源代码文件的结构更加清晰,Weather工程设置了多个命名空间,分别用来保存用户界面、数据库、后台服务和工具实体的源代码文件,源代码文件的名称以及说明如表5.1所示。
表5.1ty-weather工程的文件用途说明
包名称com.ty.weathercom.ty.weathercom.ty.weathercom.ty.weathercom.ty.weathercom.ty.weathercom.ty.weather
文件名
ConfigureActivity.javaDetailForecastActivity.ja
vaForecastProvider.javaForecastService.javaForecastTimeService.javaForecastWidget.javaWebServiceHelper.java
说
明
“设置页面”的Activity“详细页面”的Activity天气预报相关数据提供者,操作数据库
后台进程内服务后台时间服务
实现AppWidget组件,并启动服务
网络数据获取模块
com.ty.weather.utilcom.ty.weather.utilcom.ty.weather.util
ForecastEntity.javaForecastUtil.javaWidgetEntity.java
未来天气信息的类天气信息工具类当前天气信息的类
Android的资源文件保存在/res的子目录中。其中、/res/anim目录中保存的是产生动画效果的XML文件,/res/drawable/目录中保存的是图像文件,/res/values目录中保存的是用来自定义字符串和颜色的文件,/res/xml目录中保存的是XML格式的数据文件。所有在程序开发阶段可以被调用的资源都保存在这些目录中,具体每个资源文件的用途可以参考表5.2:
表5.2
资源目录
文
件
资源文件名称与用途
说
渐变透明度动画效果
画面转换位置移动动画效果(从左至右)画面转换位置移动动画效果(从右至左)画面转换位置移动动画效果(从上至下)画面转换位置移动动画效果(从上至下)画面转换位置移动动画效果(从上至下)画面转换位置移动动画效果(从上至下)画面转换位置移动动画效果(从上至下)
明
rotatecurrentweather.xmltranslatecloudleft.xmltranslatecloudright.xml
anim
translaterain01.xmltranslaterain02.xmltranslaterain03.xmltranslaterain04.xmltranslaterain05.xml
cloudy.png
drawable
dots.pngnumber_7_tahoma.pngweather_sunny.pngconfigure.xmlweather.xml
layout
detail.xmldetailitems.xml
color.xmlstrings.xmlweatherwidget.xml
这个文件夹里是工程里所用的图片,如有表示天气状况、数字等,此处不赘述。
设置城市、天气更新频率的布局“显示页面”的布局
“详细显示”页面上边的显示当前天气的布局
“详细显示”页面下边的显示未来天气的布局
保存颜色的XML文件保存字符串的XML的文件AppWidget的属性文件
valuesxml
5.2数据提供者
数据提供者ForecastProvider继承ContentProvider,是在应用程序间共享
数据的一种接口机制。应用程序在不同的进程中运行,因此,数据和文件在不同的应用程序之间是不能够直接进行访问的。而CotentProvider为程序员提供了较高级的数据共享方法,应用程序可以指定需要共享的数据,而其他应用程序则可以在不知数据来源、路径的情况下,对共享数据进行查询、添加、删除和更新等操作。
在介绍ForecastProvider的核心代码前,首先了解一下WidgetEntity.java(当前天气信息的类)和ForecastEntity.java(未来天气信息的类)。
(1)WidgetEntity.java的部分代码:
publicclassWidgetEntity{
privateArrayListdetails=newArrayList();privateIntegerid;privateStringcity;
//编号
//更新频率
//城市
//城市标记//预报时间//天气情况
privateIntegerupdateMilis;privateStringpostalCode;privateLongforecastDate;privateStringcondition;privateIntegertempF;privateIntegertempC;privateStringicon;
//ForecastEntity对象
//华氏温度//摄氏温度//湿度
//风力风向//最后更新时间//是否已设置
privateStringhumidity;
//天气图标
privateStringwindCondition;privateLonglastUpdateTime;privateIntegerisConfigured;......}
从代码中可以看出,除ForecastEntity的对象details,WidgetEntity类中有以上公有静态属性id、updateMilis、updateMilis、postalCode、
forecastDate、condition、tempF、tempC、humidity、icon、windCondition、lastUpdateTime、isConfigured,完全对应数据库中
weather_widget的表。
(2)ForecastEntity.java的部分代码:
publicclassForecastEntity{
privateIntegerid;privateIntegerlow;privateStringicon;
//编号
//星期
//最低温度//最高温度
//天气情况
//天气图标
privateStringdayOfWeek;privateIntegerhight;
privateStringcondition;
privateIntegerwidgetId;
//组件id
从代码中可以看出,WidgetEntity类中有以上公有静态属性id、dayOfWeek、low、hight、icon、condition、widgetId,完全对应数据库中weather_forcast的表。
在创建ForecastProvider时,首先需要使用数据库、文件系统或网络实现底层存储功能,这里我们采用数据库建立了数据库设计中的两张表,从而实现了底层存储功能。然后在继承ContentProvider的类中实现基本数据操作的接口函数,包括添加、删除、查找和更新等功能。下面就核心代码进行分析。(1)
创建数据库:DatabaseHelper类继承SQLiteOpenHelper,
SQLiteOpenHelper这个类可以辅助建立、更新和打开数据库。DatabaseHelper在建立数据库时,同时建立了两个数据库表weather_widget和weather_forcast,并对保存配置信息的表进行了初始化。具体代码如下所示:
privatestaticclassDatabaseHelperextendsSQLiteOpenHelper{
//数据库名称
privatestaticfinalStringDATABASE_NAME=
privatestaticfinalintDATABASE_VERSION=2;//构造方法,重载父类构造
publicDatabaseHelper(Contextcontext){
super(context,DATABASE_NAME,null,DATABASE_VERSION);}
publicvoidonCreate(SQLiteDatabasedb){//创建weather_widget表
publicvoidonCreate(SQLiteDatabasedb){
//创建weather_widget表
db.execSQL(
......);
//创建weather_forecast表
db.execSQL(
......);
}}
//重写onUpgrade()方法@Override
publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,int
newVersion){
......}}}
(2)URI设置:ContentProvider可以提供多个数据集,调用者使用URI(通用资源标识符)对不同的数据集的数据进行操作。URI用来地位任何远程或本地的可用资源。ContentProvider使用的URI语法结构content:////。因此,我们就需要先来对URI进行设置。代码如下:
publicstaticclassWeatherWidgetsimplementsBaseColumns{
//继承BaseColumns可以提供自动生成的ID
//声明CONTENT_URI
publicstaticfinalUriCONTENT_URI=Uri.parse(
+AUTHORITY+
publicstaticfinalStringFORECAST_END=
//指操作多条数据
publicstaticfinalStringCONTENT_TYPE=
//指操作单条数据
publicstaticfinalStringCONTENT_ITEM_TYPE=
}
(3)查询功能:首先我们先了解一下SQLiteQueryBuilder的query()方法。query(SQLiteDatabasedb,String[]projectionIn,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringsortOrder,Stringlimit),参数说明如表5.3:参数
要查询的数据库实例
是一个字符串数组,里边的每一项代表了需要返回的列名
相当于SQL语句中的where部分
是一个字符串数组,里边的每一项依次替代在第三个参数
中出现的问号(?)
相当于SQL语句当中的groupby部分
相当于SQL语句当中的having部分
描述是怎么进行排序
相当于SQL当中的limit部分,控制返回的数据的个数说明SQLiteDatabasedbString[]projectionInStringselectionString[]selectionArgsStringgroupByStringhavingStringsortOrderStringlimit
查询功能的核心代码如下:
publicCursorquery(Uriuri,String[]projection,Stringselection,
String[]selectionArgs,StringsortOrder){
//getReadableDatabase()这个函数会数据库是否存在、版本号和是否可读等情
况,
//决定在返回数据库对象前,是否需要数据库。返回一个可读的数据库对象。
SQLiteDatabasedb=dbHelper.getReadableDatabase();
//声明了一个SQLiteQueryBuilder对象,该对象利用传入的参数生成一个完整的
//sqlite查询语句,还可以完成查询工作并返回结果集(Cursor)。
SQLiteQueryBuilderqb=newSQLiteQueryBuilder();
Stringlimit=null;
//通过一个switch语句,完成了通过uri种类的辨别来生成不通的
SQLiteQueryBuilder对象的工作。
switch(uriMatcher.match(uri)){
caseWIDGETS:{
qb.setTables(TABLE_WIDGET);
break;
}
caseWIDGETS_ID:{
StringappWidgetId=uri.getPathSegments().get(1);
qb.setTables(TABLE_WIDGET);
qb.appendWhere(BaseColumns._ID+
break;
}
caseWIDGETS_FORECASTS:{
//Pickalltheforecastsforgivenwidget,sortedbydateand
//importance
//获得appWidgetId
StringappWidgetId=uri.getPathSegments().get(1);
//为该SQLiteQueryBuilder对象设置它查询工作将针对的表
qb.setTables(TABLE_FORECAST);//qb的where条件
qb.appendWhere(ForecastEntity.WIDGET_ID+
//按照BaseColumns._ID进行排序
sortOrder=BaseColumns._ID+
break;
}caseFORECASTS:{
qb.setTables(TABLE_FORECAST);
break;
}
caseFORECASTS_ID:{
StringforecastId=uri.getPathSegments().get(1);
qb.setTables(TABLE_FORECAST);
qb.appendWhere(BaseColumns._ID+
break;
}
}
returnqb.query(db,projection,selection,selectionArgs,null,null,sortOrder,limit);
}
(4)添加、删除、更新功能由于核心代码类似,此处不一一赘述。
添加功能:
publicUriinsert(Uriuri,ContentValuesvalues){}
删除功能:
publicintdelete(Uriuri,Stringselection,String[]selectionArgs){}更新功能:
publicintupdate(Uriuri,ContentValuesvalues,Stringselection,
String[]selectionArgs){}
(5)类型匹配:增删改查通过switch判断,进行不同的操作,因而还需要对关键字进行类型匹配。核心代码如下:
/*getType()函数用来返回指定URI的MIME数据类型
*CONTENT_TYPE表示URI是多条数据
*CONTENT_ITEM_TYPE表示是单条数据
*/
@Override
publicStringgetType(Uriuri){
//TODOAuto-generatedmethodstub
switch(uriMatcher.match(uri)){
caseWIDGETS:
returnWeatherWidgets.CONTENT_TYPE;
caseWIDGETS_ID:
returnWeatherWidgets.CONTENT_ITEM_TYPE;
caseWIDGETS_FORECASTS:
returnWeatherDetails.CONTENT_TYPE;
caseFORECASTS:
returnWeatherDetails.CONTENT_TYPE;
caseFORECASTS_ID:
returnWeatherDetails.CONTENT_ITEM_TYPE;
}
thrownewIllegalStateException();
}
//构造无匹配方式的uriMatcher
privatestaticfinalUriMatcheruriMatcher=newUriMatcher(
UriMatcher.NO_MATCH);
privatestaticfinalintWIDGETS=101;
privatestaticfinalintWIDGETS_ID=102;
privatestaticfinalintWIDGETS_FORECASTS=103;
privatestaticfinalintFORECASTS=201;
privatestaticfinalintFORECASTS_ID=202;
//声明了uriMatcher的匹配方式和返回代码
static{
uriMatcher.addURI(AUTHORITY,
uriMatcher.addURI(AUTHORITY,
uriMatcher.addURI(AUTHORITY,
WIDGETS_FORECASTS);
uriMatcher.addURI(AUTHORITY,
uriMatcher.addURI(AUTHORITY,
}
}
5.3后台服务
后台服务是ty-weather工程的核心模块,在用户启动后持续在后台运行,直到用户停止服务。后台服务主要有三个功能,一是周期性的获取Google的天气数据并存储到SQLite,二是从SQLite读取出要显示的数据,三是定时更新“显示页面”的时间。
5.3.1获取天气数据
天气数据的获取天气数据分为以下三个步骤:
(1)从Google提供的WebService中获取的天气数据,数据的获取地址是:http://www.google.com/ig/api?weather=%s&hl=zh-cn。核心代码如下:
publicstaticWidgetEntityqueryWebservice(StringpostalCode)
throwsForecastParseException{
//编码出错
if(postalCode==null){
thrownewForecastParseException(
}ReaderresponseReader;
WidgetEntitywidgetEntity=null;
//通过HttpClient创建Http连接
HttpClientclient=newDefaultHttpClient();
//创建HttpGet请求
HttpGetrequest=newHttpGet(String.format(WEBSERVICE_URL,
postalCode));
try{
Log.d(TAG,
//发出请求
HttpResponseresponse=client.execute(request);
StatusLinestatus=response.getStatusLine();
Log.d(TAG,
//取出回复信息
HttpEntityentity=response.getEntity();
responseReader=newInputStreamReader(entity.getContent(),
}catch(IOExceptione){
thrownewForecastParseException(
API
}
if(responseReader!=null){
widgetEntity=parseResponse(responseReader);
}
returnwidgetEntity;
}
(2)调用轻量级XML解析器XmlPullParser对从网络上获取的字节流数据进行解析,并且将解析结果保存在WidgetEntity对象中。核心代码如下://返回类型为WidgetEntity
privatestaticWidgetEntityparseResponse(ReaderresponseReader)
throwsForecastParseException{
......
try{
//使用工厂类XmlPullParserFactory来创建解析器XmlPullParser
XmlPullParserFactoryfactory=
XmlPullParserFactory.newInstance();
XmlPullParserxpp=factory.newPullParser();
StringtagName=null;
xpp.setInput(responseReader);
inteventType=xpp.getEventType();
while(eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_TAG){
tagName=xpp.getName();
//根据不同的标签做不同的解析
if(PROBLEM_CAUSE.equals(tagName)){
thrownewForecastParseException(
}elseif(FORECAST_INFORMATION.equals(tagName)){
dealWithInfomation(tagName,widgetEntity,xpp);
}elseif(CURRENT_CONDITIONS.equals(tagName)){
dealWithCurrentConditions(tagName,widgetEntity,
xpp);
}elseif(FORECAST_CONDITIONS.equals(tagName)){
dealWithForecastConditions(tagName,widgetEntity,
xpp);
}
}
eventType=xpp.next();
}
}catch(IOExceptione){
......
}
returnwidgetEntity;
}
(3)将解析好的数据存储到SQLite数据库中。其过程是:使用ContentResolver对象,通过URI间接调用ContentProvider,使用ContentResolver对象与ContentProvider进行交互,而ContentResolver则通过URI确定需要访问的ContentProvider的数据集。核心代码如下,调用关系如图5.1所示。
图5.1ContentProvider调用关系ContentResolverresolver=context.getContentResolver();
resolver.delete(forecastUri,null,null);
ContentValuesvalues=newContentValues();
for(ForecastEntityforecast:widgetEntity.getDetails()){
values.clear();
values.put(ForecastEntity.DAYOFWEEK,forecast.getDayOfWeek());......
resolver.insert(forecastUri,values);
}
注意:
for(ForecastEntityforecast:widgetEntity.getDetails())相当于foreach语句,在widgetEntity.getDetails()集合里打印出所有类型为ForecastEntity的forecast变量。
5.3.2读取天气数据实例
通过WebServiceHelper.getWidgetEntity()方法操作数据库取出所需要的数据,这一部分与上一节的“将解析好的数据存储到SQLite数据库中”的关键点相同,为节约篇幅,此处不赘述。
5.3.3定时更新时间。
AppWidget一启动就会启动ForcastTimeService这个后台服务,此服务设置了每隔20秒刷新一次时间,“显示页面”通过这个后台服务获取系统时间从而显示。核心代码如下:
AlarmManageralarmManager=
(AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,now+updateMilis,
pendingIntent);
至此,后台服务介绍完毕,最后还需要在AndroidManifest.xml文件中注册后台服务。
5.4用户界面
在用户界面设计上,采用了AppWidget框架结构,提供直观的交互操作。三个用户界面风格简约、操作简便,用户体验将非常好。
5.4.1程序入口类ForecastWidget
ForecastWidget在设计上采用了AppWidget框架结构,AppWidget就是
HomeScreen上显示的小部件,通过在HomeScreen空白处长按,在弹出的对话框
中选择Widget部件来进行创建。此外,长按部件后并拖动到垃圾箱里进行删除。创建AppWidget需要以下四个步骤:
(1)定义Widget布局文件,此文件是res/layout/weather.xml,采用
AbsoluteLayout方式进行布局需要注意的是在这个文件中所使用的组件必须是RemoteViews所支持的。
(2)定义Widget的基本属性文件,此文件是/res/xml/weatherwidget.xml。代码如下:
xmlns:android=http://schemas.android.com/apk/res/android
android:initialLayout=
//在启动前首先要启动ConfigureActivity进行设置
android:configure=
android:minWidth=
android:minHeight=
//更新的时间周期android:updatePeriodMillis=
(3)创建ForecastWidget.java类,此类继承自AppWidgetProvider,主要的功能有:
获取需要更新的桌面小控件;启动获取天气预报信息的服务;启动时间信息的服务;更新桌面小控件显示内容;更新时间信息。核心代码如下:
publicclassForecastWidgetextendsAppWidgetProvider{
@Override
publicvoidonUpdate(Contextcontext,AppWidgetManager
appWidgetManager,int[]appWidgetIds){
super.onUpdate(context,appWidgetManager,appWidgetIds);
//获取需要更新的桌面小控件
ForecastService.addWidgetIDs(appWidgetIds);
//启动获取天气预报信息的服务
context.startService(newIntent(context,ForecastService.class));
//启动时间信息的服务
context.startService(newIntent(context,
ForecastTimeService.class));
}
//更新桌面小空间显示内容
publicstaticRemoteViewsupdateViews(Contextcontext,Uriuri){
}
//更新时间信息
publicstaticRemoteViewsupdateTime(Contextcontext){
}
(4)AppWidgetProvider对应一个receiver属性,需要更新AndroidManifest.xml。代码如下:
密级:
学士学位论文
THESISOFBACHELOR
(2007—2011
年)
题目:基于Android平台的3G气象软件
学专学院:软件学院系业:号:计算机软件计算机软件
姓名:指导教师:起讫日期:南昌大学
学士学位论文原创性申明
本人郑重申明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。对本文的研究作出重要贡献的个人和集体,均已在文中以明确方式表明。本人完全意识到本申明的法律后果由本人承担。
作者签名:日期:
学位论文版权使用授权书
本学位论文作者完全了解学校有关保留、使用学位论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。本人授权南昌大学可以将本论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。
保密□,在
本学位论文属于
不保密□。
(请在以上相应方框内打“√”)
作者签名:日期:年解密后适用本授权书。
导师签名:日期:
Android平台3G手机气象软件
专业:计算机软件学号:
学生姓名:指导老师:
摘要
随着智能手机的快速普及,智能手机操作系统市场风生水起。为了让智能手机用户能够随时随地查询互联网所提供的服务,一种高效的办法就是将应用系统的功能拓展到手机终端上,让手机能够通过移动网以及互联网访问Web网站并处理各种各样的业务。因此,智能手机的应用软件及其需要的服务将有广阔的发展前景。
在如今这个智能手机系统群雄纷争的时候,2008年Google推出了一款名为Android的开源智能手机操作系统,它采用Linux内核,开放手机联盟(OHA)成员可以任意使用和修改SDK包,系统的开源性使其具有良好的拓展性。这款软件包括了操作系统、用户界面和应用程序,即智能手机工作所需要的全部软件。Android的最大特点是其开放性体系架构,不仅具有非常好的开发、调试环境,而且还支持各种可扩展的用户体验,包括丰富的图形组件、多媒体支持功能以及强大的浏览器。因此,对于软件从业人员来说,Android平台具有无限的吸引力。
本文就在分析讨论Android手机软件开发技术原理的基础上,开发出能为用户提供更好的基于Android平台的3G手机气象软件。
关键字:android;气象软件;智能手机平台
Abstract
Withtherapidproliferationofsmartphones,smartphoneoperatingsystemmarket,windandwater.InorderforsmartphoneuserstochecktheInternetanytime,anywhereservicesprovidedanefficientwaytoexpandthefunctionofthesystemwillbeappliedtothemobilephoneterminal,themobilephonetoInternetaccessviamobilenetworks,andvarietyofWebsitesandprocessbusiness.Therefore,thesmartphoneapplicationsandtheneedfortheservicewillhavebroadprospectsfordevelopment.
Intoday'ssmartphonesystemwhendisputeswarlords,2008,GoogleintroducedasmartphonecalledtheAndroidopensourceoperatingsystem,whichusesLinuxkernel,OpenHandsetAlliance(OHA)memberscanbefreetouseandmodifytheSDKpackage,thesystemIthasagoodopen-sourcenatureoftheexpansionof.Thesoftwareincludestheoperatingsystem,userinterfaceandapplicationsthatneedtoworksmartphonesallthesoftware.Android'sbiggestfeatureisitsopenarchitecture,notonlyhasaverygooddevelopmentanddebuggingenvironment,butalsosupportsavarietyofscalableuserexperience,includingrichgraphicalcomponents,multimediasupport,andpowerfulbrowser.Therefore,forsoftwareprofessionalsis,Androidplatformhasunlimitedappeal.
Inthispaper,theanalysisanddiscussionAndroidmobilephonesoftwaredevelopmenttechnologyonthebasisoftheprinciple,developedtoprovideuserswithbetterplatformtothe3GhandsetsbasedonAndroidmeteorologicalsoftware.Keywords:android;weathersoftware;smartphoneplatform
目录
摘要............................................................................................................................IAbstract..........................................................................................................................II
第一章绪论....................................................................................................................1
1.1研究内容.......................................................................................................1
1.2研究意义.......................................................................................................11.3研究现状和发展趋势...................................................................................1
第二章系统分析........................................................................................................3
2.1研究目标..........................................................................................................3
2.2需求分析..........................................................................................................3
2.3性能分析..........................................................................................................3
第三章系统开发环境及相关技术..............................................................................4
3.1Android开发环境介绍...................................................................................4
3.2
4.1
4.2
4.3
5.1
5.2
5.3Android开发平台搭建.................................................................................4用户界面设计................................................................................................6数据库设计....................................................................................................6程序模块设计................................................................................................7文件结构与用途............................................................................................9数据提供者..................................................................................................10后台服务......................................................................................................16
5.3.1
5.3.2
5.3.3
5.4
5.4.1
5.4.2获取天气数据....................................................................................16读取天气数据实例............................................................................19定时更新时间。................................................................................19程序入口类ForecastWidget..............................................................19设置页面ConfigureActivity..............................................................21第四章程序设计..........................................................................................................6第五章程序开发............................................................................................................9用户界面......................................................................................................19
5.4.3详细页面DetailForecastActivity........................................................22
5.5动态特效........................................................................................................23
第六章系统测试......................................................................................................25
第七章总结..................................................................................................................29
参考文献......................................................................................................................30致谢..........................................................................................................................31
第一章绪论
1.1研究内容
Android平台3G手机气象软件是基于Android手机平台,运用Java语言,从Google上获取天气预报信息,开发出针对使用Android平台的手机天气预报系统。
1.2研究意义
Android平台3G手机气象软件的开发可以进一步扩大气象信息的覆盖面,让广大公众能够在第一时间方便且快捷地获取最新的气象预报(预警)信息,以便提前预防,把气象灾害造成的损失降到最低。同时也可以强化气象公共服务的职能,完善公共服务体系、改善公共服务手段、增加公共服务产品、提高公共服务质量,更好地发挥了气象事业对经济社会发展的现实性作用。
1.3研究现状和发展趋势
据Gartner最新数据显示,2010年第二、三季度全球智能手机销售继续大幅增长,其中第三季度安卓占全球智能手机市场的25.5%,仅次于塞班,成为第二大智能手机系统。2010第二、三季度与去年同期相比,增度分别是15.4%及22%,增势迅猛。而塞班系统较09年的市场份额,尽管终端销量有大幅度提升,但增势下滑
10%,形势非常严峻。其他操作系统的表现则要平稳很多。
安卓是首款开源代码的操作系统,采用Linux内核,开放手机联盟(OHA)成员可以任意使用和修改安卓的SDK软件包。系统的开源性使其具有良好的拓展性,一方面,为众多移动应用开发者提供了良好的系统性平台,有利于移动应用的集合;另一方面,终端厂商可以针对自身的特殊需要“定制化开发”。与此相比,尽管2010年2月,塞班基本完成开源工作,但由于代码臃肿,用户界面设计缺失,塞班的开源并无实际意义,错失发展良机。
据Informa预测,2012年,安卓手机销量将超过诺基亚塞班手机,届时安卓将成为全球最大的智能手机平台。谷歌表示目前安卓手机每日平均激活量为20万部,销售速度加速上涨。
我们认为,安卓在全球市场的成长壮大,塞班市场份额不断下跌已成不争事实。安卓操作系统发展迅猛主要得益于免费、开源和良好产业运作策略,这三点为安卓在智能手机市场赢得更多的发展机遇。系统的免费让更多的厂商加入,推动了份额的上升;代码的开源让更多的开发者进入应用开发;应用的丰富吸引了更多用户选择,这也是谷歌值得众多厂商学习的地方。此外,谷歌通过OHA联合众多厂商进行系统研发,不断更新版本,将系统应用推广到更多的终端产品中,确保用户体验持续改善。
第一章系统分析
第二章系统分析
2.1研究目标
(1)了解Android应用程序的设计和开发过程;
(2)使用多种组件进行Android平台3G手机气象软件的开发。
本软件是基于Eclipse的开发环境,依托Google气象数据建立气象信息数据库,开发出了针对Android平台的手机天气预报系统。
2.2需求分析
本软件是一个AppWidget应用程序,启动程序后可以进行城市、更新频率的设置,可以通过图片和文字显示当前和未来的天气状况,包括温度、湿度、风向和雨雪情况等。这些天气数据是通过后台服务获取的,这个后台服务可以按照一定时间间隔,从Google上获取天气预报信息,并将天气信息保存在数据库中。
从上面的描述中可以基本了解软件的功能需求:
(1)启动AppWidget应用程序;
(2)设置界面:对要显示天气预报的城市及更新频率进行设置;
(3)显示界面:通过文字和图片显示当前的天气情况,包括日期、时间、城市、
最高温度、最低温度、当前温度等。
(4)详细界面:通过文字图片动画显示当前的天气情况,包括城市当前天气、温
度、风向、风速、湿度;同时显示今后四天的天气情况。
2.3性能分析
程序响应速度快、安全性高、信息处理速度快。
第三章系统开发环境及相关技术
3.1Android开发环境介绍
Android的上层应用程序是用Java语言开发,同时还需要基于Dalvik虚拟机,所以,Google公司推荐使用主流的Java继承开发环境Eclipse。只有Eclipse还不够,因为是使用Java语言进行开发,还应该有由SUN公司提供的JavaSDK(其中包括JRE:JavaRuntimeEnvironment)。此外,Android的应用程序开发和Java开发有较大区别的,所以还需要有Google提供的AndroidSDK。同时,还需要在Eclipse安装ADT,为Android开发提供开发工具的升级或者变更,是Eclipse下开发工具的升级下载的工具。
简言之,需要以下软件,才能搭建Android开发环境,从而进行Android应用程序的开发。(1)JavaSDK(2)Eclipse(3)AndroidSDK(4)ADT3.2
Android开发平台搭建
Android开发平台搭建步骤:
①首先到http://www.eclipse.org/downloads/下载Eclipse集成开发环境并且解压,这里推荐下载JavaEE集成版本,可以为平台的搭建省下不少工作。接着再去http://java.sun.com/javase/downloads/index.jsp站点下载SDK后安装,下载http://dl.google.com/android/android-sdk-windows-1.5_r1.zip,AndroidSDK1.5后解压。第一步下载工序就结束了。
②双击Eclipse解压后目录中的eclipse.exe然后启动,选择Eclipse菜单中的Help->InstallNewSoftware->选项卡上的AvailableSoftware,点击右侧的“Add”输入http://dl-ssl.google.com/android/eclipse/后确定,然后在“Workwith”下拉菜单中选择刚才输入的网址。过一会就会出现一个DeveloperTools选项,勾上以后点击Next以后Eclipse会自动网上查找Android开发工具插件,然后找到AndroidDDMS和AndroidDevelopmentTools,选中这两个点击Finish,Eclipse就会自动下载并安装Android插件了,最后会提示
重启Eclipse。
③重启后选择Eclipse菜单中的Windows->Preferences在左侧的Android项目中SDKLocation中填入AndroidSDK解压后的目录,然后点击Apply。④在WindowsXP的系统变量中的path变量中添加一个值,该值指向解压后的AndroidSDK目录下的tools文件夹。
第四章程序设计
4.1用户界面设计
根据需求分析可以知道,应用程序应包含三个主要的用户界面,这里需要进
一步分析每个用户界面中应该包括哪些显示内容。
在“设置页面”中,需要对要显示天气预报的城市及更新频率进行设置。在“显示页面”中,显示当前的天气状况,包括城市名称、温度、湿度、风向、雨雪情况和获取数据时间等信息。在“详细页面”动态显示当前天气情况,还要显示未来四天的天气情况。
根据对用户界面显示内容的分析,绘制出用户界面的草图,如图4-1
所示。
图4-1用户界面草图
4.2数据库设计
本软件中有两部分数据需要存储,一个是显示页面的数据,另一个详细页
面的数据。因此选择SQLite数据库作为存储数据的方法,建立数据库forcasts.db,并且建立两张表weather_forcastt和weather_widget,分别存储显示页面的数据和详细页面的数据。
表4-1详细页面的数据库表weather_forcast的结构属性_idwidgetIddayOfWeek
low
数据类型integerintegertextinteger
自动增加的主键组件的ID号周几最低温度
说明
highticoncondition
integertexttext
最高温度显示天气的图标未来天气情况
表4-2显示页面的数据库表weather_widget的结构
属性_idcityupdateMilisisConfiguredpostalCodeforecastDateconditiontempFtempChumidityiconwindConditionlastUpdateTime
数据类型integertexttexttexttextintegertextintegerintegertexttexttextinteger
存储Widget组件id进行天气信息查询的城市名
进行天气信息查询的频率,单位为分/次是否设置城市标记预报日期当前天气情况最高温度最低温度当前湿度天气图标风向风速情况最后一次更新时间
说明
4.3程序模块设计
从功能需求上分析可以看出,整个应用程序应划分为4个模块,分别是程
序启动、用户界面、后台服务和数据库适配器,各模块之间的关系如图4-2所示。
从模块结构图中不难看出,后台服务是整个应用程序的核心,主要是“数据获取模块”,负责周期性的从Google获取天气信息。后台服务在程序启动时就由AppWidgetProvider启动,也可由用户界面通过startService()进行启动,启动后的后台服务将一直保持运行状态。
用户界面从数据库中获取天气信息,而没有直接通过网络访问Google的天气数据。之所以这么实际,一方面可以避免因网络通信不畅造成界面失去响应;另一方面,后台服务可以及时更新数据,以保证数据的准确性。
数据库适配器封装了所有对SQLite数据库操作的方法,用户界面和后台服务会调用它来实现数据库操作。
在完成用户界面设计、数据库设计和模块设计后,至此程序设计阶段基本完成。
第五章程序开发
5.1文件结构与用途
在程序开发阶段,首先确定“Android平台3G手机气象软件”的工程名为
ty-weather,据程序模块设计的内容,建立ty-weather工程。Weather工程源代码的结构如图5.1
所示。
图5.1ty-weather工程的源代码文件
为了使源代码文件的结构更加清晰,Weather工程设置了多个命名空间,分别用来保存用户界面、数据库、后台服务和工具实体的源代码文件,源代码文件的名称以及说明如表5.1所示。
表5.1ty-weather工程的文件用途说明
包名称com.ty.weathercom.ty.weathercom.ty.weathercom.ty.weathercom.ty.weathercom.ty.weathercom.ty.weather
文件名
ConfigureActivity.javaDetailForecastActivity.ja
vaForecastProvider.javaForecastService.javaForecastTimeService.javaForecastWidget.javaWebServiceHelper.java
说
明
“设置页面”的Activity“详细页面”的Activity天气预报相关数据提供者,操作数据库
后台进程内服务后台时间服务
实现AppWidget组件,并启动服务
网络数据获取模块
com.ty.weather.utilcom.ty.weather.utilcom.ty.weather.util
ForecastEntity.javaForecastUtil.javaWidgetEntity.java
未来天气信息的类天气信息工具类当前天气信息的类
Android的资源文件保存在/res的子目录中。其中、/res/anim目录中保存的是产生动画效果的XML文件,/res/drawable/目录中保存的是图像文件,/res/values目录中保存的是用来自定义字符串和颜色的文件,/res/xml目录中保存的是XML格式的数据文件。所有在程序开发阶段可以被调用的资源都保存在这些目录中,具体每个资源文件的用途可以参考表5.2:
表5.2
资源目录
文
件
资源文件名称与用途
说
渐变透明度动画效果
画面转换位置移动动画效果(从左至右)画面转换位置移动动画效果(从右至左)画面转换位置移动动画效果(从上至下)画面转换位置移动动画效果(从上至下)画面转换位置移动动画效果(从上至下)画面转换位置移动动画效果(从上至下)画面转换位置移动动画效果(从上至下)
明
rotatecurrentweather.xmltranslatecloudleft.xmltranslatecloudright.xml
anim
translaterain01.xmltranslaterain02.xmltranslaterain03.xmltranslaterain04.xmltranslaterain05.xml
cloudy.png
drawable
dots.pngnumber_7_tahoma.pngweather_sunny.pngconfigure.xmlweather.xml
layout
detail.xmldetailitems.xml
color.xmlstrings.xmlweatherwidget.xml
这个文件夹里是工程里所用的图片,如有表示天气状况、数字等,此处不赘述。
设置城市、天气更新频率的布局“显示页面”的布局
“详细显示”页面上边的显示当前天气的布局
“详细显示”页面下边的显示未来天气的布局
保存颜色的XML文件保存字符串的XML的文件AppWidget的属性文件
valuesxml
5.2数据提供者
数据提供者ForecastProvider继承ContentProvider,是在应用程序间共享
数据的一种接口机制。应用程序在不同的进程中运行,因此,数据和文件在不同的应用程序之间是不能够直接进行访问的。而CotentProvider为程序员提供了较高级的数据共享方法,应用程序可以指定需要共享的数据,而其他应用程序则可以在不知数据来源、路径的情况下,对共享数据进行查询、添加、删除和更新等操作。
在介绍ForecastProvider的核心代码前,首先了解一下WidgetEntity.java(当前天气信息的类)和ForecastEntity.java(未来天气信息的类)。
(1)WidgetEntity.java的部分代码:
publicclassWidgetEntity{
privateArrayListdetails=newArrayList();privateIntegerid;privateStringcity;
//编号
//更新频率
//城市
//城市标记//预报时间//天气情况
privateIntegerupdateMilis;privateStringpostalCode;privateLongforecastDate;privateStringcondition;privateIntegertempF;privateIntegertempC;privateStringicon;
//ForecastEntity对象
//华氏温度//摄氏温度//湿度
//风力风向//最后更新时间//是否已设置
privateStringhumidity;
//天气图标
privateStringwindCondition;privateLonglastUpdateTime;privateIntegerisConfigured;......}
从代码中可以看出,除ForecastEntity的对象details,WidgetEntity类中有以上公有静态属性id、updateMilis、updateMilis、postalCode、
forecastDate、condition、tempF、tempC、humidity、icon、windCondition、lastUpdateTime、isConfigured,完全对应数据库中
weather_widget的表。
(2)ForecastEntity.java的部分代码:
publicclassForecastEntity{
privateIntegerid;privateIntegerlow;privateStringicon;
//编号
//星期
//最低温度//最高温度
//天气情况
//天气图标
privateStringdayOfWeek;privateIntegerhight;
privateStringcondition;
privateIntegerwidgetId;
//组件id
从代码中可以看出,WidgetEntity类中有以上公有静态属性id、dayOfWeek、low、hight、icon、condition、widgetId,完全对应数据库中weather_forcast的表。
在创建ForecastProvider时,首先需要使用数据库、文件系统或网络实现底层存储功能,这里我们采用数据库建立了数据库设计中的两张表,从而实现了底层存储功能。然后在继承ContentProvider的类中实现基本数据操作的接口函数,包括添加、删除、查找和更新等功能。下面就核心代码进行分析。(1)
创建数据库:DatabaseHelper类继承SQLiteOpenHelper,
SQLiteOpenHelper这个类可以辅助建立、更新和打开数据库。DatabaseHelper在建立数据库时,同时建立了两个数据库表weather_widget和weather_forcast,并对保存配置信息的表进行了初始化。具体代码如下所示:
privatestaticclassDatabaseHelperextendsSQLiteOpenHelper{
//数据库名称
privatestaticfinalStringDATABASE_NAME=
privatestaticfinalintDATABASE_VERSION=2;//构造方法,重载父类构造
publicDatabaseHelper(Contextcontext){
super(context,DATABASE_NAME,null,DATABASE_VERSION);}
publicvoidonCreate(SQLiteDatabasedb){//创建weather_widget表
publicvoidonCreate(SQLiteDatabasedb){
//创建weather_widget表
db.execSQL(
......);
//创建weather_forecast表
db.execSQL(
......);
}}
//重写onUpgrade()方法@Override
publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,int
newVersion){
......}}}
(2)URI设置:ContentProvider可以提供多个数据集,调用者使用URI(通用资源标识符)对不同的数据集的数据进行操作。URI用来地位任何远程或本地的可用资源。ContentProvider使用的URI语法结构content:////。因此,我们就需要先来对URI进行设置。代码如下:
publicstaticclassWeatherWidgetsimplementsBaseColumns{
//继承BaseColumns可以提供自动生成的ID
//声明CONTENT_URI
publicstaticfinalUriCONTENT_URI=Uri.parse(
+AUTHORITY+
publicstaticfinalStringFORECAST_END=
//指操作多条数据
publicstaticfinalStringCONTENT_TYPE=
//指操作单条数据
publicstaticfinalStringCONTENT_ITEM_TYPE=
}
(3)查询功能:首先我们先了解一下SQLiteQueryBuilder的query()方法。query(SQLiteDatabasedb,String[]projectionIn,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringsortOrder,Stringlimit),参数说明如表5.3:参数
要查询的数据库实例
是一个字符串数组,里边的每一项代表了需要返回的列名
相当于SQL语句中的where部分
是一个字符串数组,里边的每一项依次替代在第三个参数
中出现的问号(?)
相当于SQL语句当中的groupby部分
相当于SQL语句当中的having部分
描述是怎么进行排序
相当于SQL当中的limit部分,控制返回的数据的个数说明SQLiteDatabasedbString[]projectionInStringselectionString[]selectionArgsStringgroupByStringhavingStringsortOrderStringlimit
查询功能的核心代码如下:
publicCursorquery(Uriuri,String[]projection,Stringselection,
String[]selectionArgs,StringsortOrder){
//getReadableDatabase()这个函数会数据库是否存在、版本号和是否可读等情
况,
//决定在返回数据库对象前,是否需要数据库。返回一个可读的数据库对象。
SQLiteDatabasedb=dbHelper.getReadableDatabase();
//声明了一个SQLiteQueryBuilder对象,该对象利用传入的参数生成一个完整的
//sqlite查询语句,还可以完成查询工作并返回结果集(Cursor)。
SQLiteQueryBuilderqb=newSQLiteQueryBuilder();
Stringlimit=null;
//通过一个switch语句,完成了通过uri种类的辨别来生成不通的
SQLiteQueryBuilder对象的工作。
switch(uriMatcher.match(uri)){
caseWIDGETS:{
qb.setTables(TABLE_WIDGET);
break;
}
caseWIDGETS_ID:{
StringappWidgetId=uri.getPathSegments().get(1);
qb.setTables(TABLE_WIDGET);
qb.appendWhere(BaseColumns._ID+
break;
}
caseWIDGETS_FORECASTS:{
//Pickalltheforecastsforgivenwidget,sortedbydateand
//importance
//获得appWidgetId
StringappWidgetId=uri.getPathSegments().get(1);
//为该SQLiteQueryBuilder对象设置它查询工作将针对的表
qb.setTables(TABLE_FORECAST);//qb的where条件
qb.appendWhere(ForecastEntity.WIDGET_ID+
//按照BaseColumns._ID进行排序
sortOrder=BaseColumns._ID+
break;
}caseFORECASTS:{
qb.setTables(TABLE_FORECAST);
break;
}
caseFORECASTS_ID:{
StringforecastId=uri.getPathSegments().get(1);
qb.setTables(TABLE_FORECAST);
qb.appendWhere(BaseColumns._ID+
break;
}
}
returnqb.query(db,projection,selection,selectionArgs,null,null,sortOrder,limit);
}
(4)添加、删除、更新功能由于核心代码类似,此处不一一赘述。
添加功能:
publicUriinsert(Uriuri,ContentValuesvalues){}
删除功能:
publicintdelete(Uriuri,Stringselection,String[]selectionArgs){}更新功能:
publicintupdate(Uriuri,ContentValuesvalues,Stringselection,
String[]selectionArgs){}
(5)类型匹配:增删改查通过switch判断,进行不同的操作,因而还需要对关键字进行类型匹配。核心代码如下:
/*getType()函数用来返回指定URI的MIME数据类型
*CONTENT_TYPE表示URI是多条数据
*CONTENT_ITEM_TYPE表示是单条数据
*/
@Override
publicStringgetType(Uriuri){
//TODOAuto-generatedmethodstub
switch(uriMatcher.match(uri)){
caseWIDGETS:
returnWeatherWidgets.CONTENT_TYPE;
caseWIDGETS_ID:
returnWeatherWidgets.CONTENT_ITEM_TYPE;
caseWIDGETS_FORECASTS:
returnWeatherDetails.CONTENT_TYPE;
caseFORECASTS:
returnWeatherDetails.CONTENT_TYPE;
caseFORECASTS_ID:
returnWeatherDetails.CONTENT_ITEM_TYPE;
}
thrownewIllegalStateException();
}
//构造无匹配方式的uriMatcher
privatestaticfinalUriMatcheruriMatcher=newUriMatcher(
UriMatcher.NO_MATCH);
privatestaticfinalintWIDGETS=101;
privatestaticfinalintWIDGETS_ID=102;
privatestaticfinalintWIDGETS_FORECASTS=103;
privatestaticfinalintFORECASTS=201;
privatestaticfinalintFORECASTS_ID=202;
//声明了uriMatcher的匹配方式和返回代码
static{
uriMatcher.addURI(AUTHORITY,
uriMatcher.addURI(AUTHORITY,
uriMatcher.addURI(AUTHORITY,
WIDGETS_FORECASTS);
uriMatcher.addURI(AUTHORITY,
uriMatcher.addURI(AUTHORITY,
}
}
5.3后台服务
后台服务是ty-weather工程的核心模块,在用户启动后持续在后台运行,直到用户停止服务。后台服务主要有三个功能,一是周期性的获取Google的天气数据并存储到SQLite,二是从SQLite读取出要显示的数据,三是定时更新“显示页面”的时间。
5.3.1获取天气数据
天气数据的获取天气数据分为以下三个步骤:
(1)从Google提供的WebService中获取的天气数据,数据的获取地址是:http://www.google.com/ig/api?weather=%s&hl=zh-cn。核心代码如下:
publicstaticWidgetEntityqueryWebservice(StringpostalCode)
throwsForecastParseException{
//编码出错
if(postalCode==null){
thrownewForecastParseException(
}ReaderresponseReader;
WidgetEntitywidgetEntity=null;
//通过HttpClient创建Http连接
HttpClientclient=newDefaultHttpClient();
//创建HttpGet请求
HttpGetrequest=newHttpGet(String.format(WEBSERVICE_URL,
postalCode));
try{
Log.d(TAG,
//发出请求
HttpResponseresponse=client.execute(request);
StatusLinestatus=response.getStatusLine();
Log.d(TAG,
//取出回复信息
HttpEntityentity=response.getEntity();
responseReader=newInputStreamReader(entity.getContent(),
}catch(IOExceptione){
thrownewForecastParseException(
API
}
if(responseReader!=null){
widgetEntity=parseResponse(responseReader);
}
returnwidgetEntity;
}
(2)调用轻量级XML解析器XmlPullParser对从网络上获取的字节流数据进行解析,并且将解析结果保存在WidgetEntity对象中。核心代码如下://返回类型为WidgetEntity
privatestaticWidgetEntityparseResponse(ReaderresponseReader)
throwsForecastParseException{
......
try{
//使用工厂类XmlPullParserFactory来创建解析器XmlPullParser
XmlPullParserFactoryfactory=
XmlPullParserFactory.newInstance();
XmlPullParserxpp=factory.newPullParser();
StringtagName=null;
xpp.setInput(responseReader);
inteventType=xpp.getEventType();
while(eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_TAG){
tagName=xpp.getName();
//根据不同的标签做不同的解析
if(PROBLEM_CAUSE.equals(tagName)){
thrownewForecastParseException(
}elseif(FORECAST_INFORMATION.equals(tagName)){
dealWithInfomation(tagName,widgetEntity,xpp);
}elseif(CURRENT_CONDITIONS.equals(tagName)){
dealWithCurrentConditions(tagName,widgetEntity,
xpp);
}elseif(FORECAST_CONDITIONS.equals(tagName)){
dealWithForecastConditions(tagName,widgetEntity,
xpp);
}
}
eventType=xpp.next();
}
}catch(IOExceptione){
......
}
returnwidgetEntity;
}
(3)将解析好的数据存储到SQLite数据库中。其过程是:使用ContentResolver对象,通过URI间接调用ContentProvider,使用ContentResolver对象与ContentProvider进行交互,而ContentResolver则通过URI确定需要访问的ContentProvider的数据集。核心代码如下,调用关系如图5.1所示。
图5.1ContentProvider调用关系ContentResolverresolver=context.getContentResolver();
resolver.delete(forecastUri,null,null);
ContentValuesvalues=newContentValues();
for(ForecastEntityforecast:widgetEntity.getDetails()){
values.clear();
values.put(ForecastEntity.DAYOFWEEK,forecast.getDayOfWeek());......
resolver.insert(forecastUri,values);
}
注意:
for(ForecastEntityforecast:widgetEntity.getDetails())相当于foreach语句,在widgetEntity.getDetails()集合里打印出所有类型为ForecastEntity的forecast变量。
5.3.2读取天气数据实例
通过WebServiceHelper.getWidgetEntity()方法操作数据库取出所需要的数据,这一部分与上一节的“将解析好的数据存储到SQLite数据库中”的关键点相同,为节约篇幅,此处不赘述。
5.3.3定时更新时间。
AppWidget一启动就会启动ForcastTimeService这个后台服务,此服务设置了每隔20秒刷新一次时间,“显示页面”通过这个后台服务获取系统时间从而显示。核心代码如下:
AlarmManageralarmManager=
(AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,now+updateMilis,
pendingIntent);
至此,后台服务介绍完毕,最后还需要在AndroidManifest.xml文件中注册后台服务。
5.4用户界面
在用户界面设计上,采用了AppWidget框架结构,提供直观的交互操作。三个用户界面风格简约、操作简便,用户体验将非常好。
5.4.1程序入口类ForecastWidget
ForecastWidget在设计上采用了AppWidget框架结构,AppWidget就是
HomeScreen上显示的小部件,通过在HomeScreen空白处长按,在弹出的对话框
中选择Widget部件来进行创建。此外,长按部件后并拖动到垃圾箱里进行删除。创建AppWidget需要以下四个步骤:
(1)定义Widget布局文件,此文件是res/layout/weather.xml,采用
AbsoluteLayout方式进行布局需要注意的是在这个文件中所使用的组件必须是RemoteViews所支持的。
(2)定义Widget的基本属性文件,此文件是/res/xml/weatherwidget.xml。代码如下:
xmlns:android=http://schemas.android.com/apk/res/android
android:initialLayout=
//在启动前首先要启动ConfigureActivity进行设置
android:configure=
android:minWidth=
android:minHeight=
//更新的时间周期android:updatePeriodMillis=
(3)创建ForecastWidget.java类,此类继承自AppWidgetProvider,主要的功能有:
获取需要更新的桌面小控件;启动获取天气预报信息的服务;启动时间信息的服务;更新桌面小控件显示内容;更新时间信息。核心代码如下:
publicclassForecastWidgetextendsAppWidgetProvider{
@Override
publicvoidonUpdate(Contextcontext,AppWidgetManager
appWidgetManager,int[]appWidgetIds){
super.onUpdate(context,appWidgetManager,appWidgetIds);
//获取需要更新的桌面小控件
ForecastService.addWidgetIDs(appWidgetIds);
//启动获取天气预报信息的服务
context.startService(newIntent(context,ForecastService.class));
//启动时间信息的服务
context.startService(newIntent(context,
ForecastTimeService.class));
}
//更新桌面小空间显示内容
publicstaticRemoteViewsupdateViews(Contextcontext,Uriuri){
}
//更新时间信息
publicstaticRemoteViewsupdateTime(Contextcontext){
}
(4)AppWidgetProvider对应一个receiver属性,需要更新AndroidManifest.xml。代码如下: