天气预报APP论文
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
摘要 (1)
需求分析 (2)
一、开发背景 (2)
二、项目需求分析 (2)
总体设计 (2)
一、系统规划 (2)
二、系统功能界面 ....................................................................................................................... 31. 设置预报城市界面: .. (3)
2.天气显示界面: (4)
3.Widget桌面小部件界面: (5)
三.设计目标 (6)
系统设计 (6)
一、开发及运行环境 (6)
二、数据库设计 (6)
三、主要方法及步骤 (7)
四、主要方法及技术 (7)
主要模块 (7)
一、项目框架 (7)
二、主要功能实现 (8)
1.获取城市码db_weather.db数据库文件 (8)
2.实现可伸缩性列表的的构建与过滤 (12)
3.GPS定位功能的实现 (15)
4.Widget窗体小部件的更新 (18)
功能测试 (19)
结论 (23)
Window 操作系统的诞生成就了微软帝国,同时也造就了PC 时代的繁荣,然而如今,以Android 和iPhone 手机为代表的智能移动设备的发明与互联网云技术的兴起却敲响了PC 时代的丧钟!这也预示着移动互联网时代(3G)已经来临。
在这个互联网繁荣的时代,有一颗超新星,以它独特性能优势与人性化的UI 设计使它在短短的几年迅速的占领了智能移动设备的市场份额,它就是Google 的Android!这也意味着Google 在移动互联网时代开始抢跑并领跑。
Android 是基于Linux 平台完全开源的手机操作系统,同时开发语言为Java,这对于Java 开发的我们是何等的诱人,程序员的技术要与时代同行,因此我选择了以Android 为平台的手机天气预报系统来作为我的毕业设计,选择手机天气预报系统不仅可以提升技术,同时也很实用,为人们时刻了解天气状况和出行带来了方便。
需求分析
一、开发背景
近几年来随着3G 技术成熟和智能手机的不断普及,移动应用的需求与日俱增,移动应用开发成为当下最热门的技术之一。
在Google 和Android 手机联盟
的共同推动下,Android 在众多移动应用开发平台中脱颖而出。
Android 是一个
真正意义上的开源智能手机操作系统,该系统一经推出立即受到全球移动设备
厂商和开发者的热捧。
为顺应潮流,本设计旨在搭载Android 的移动设备上运行,
实现天气状况的实时动态更新与显示,方便人们的出行与生活。
二、项目需求分析
根据功能的需求,分析此项目的主要功能应具备以下几点:
1.精确查询定位全国各地城市未来几天内的实时天气状况
2.系统要具的实用性,符合用户查看信息习惯,界面设计优美
3.系统要具有稳定性,且在一定程度上节省流量的开销
总体设计
一、系统规划
由上述的需求,现将系统分为三大模块:天气显示界面模块、预报城市设
置模块与Widget 桌面小部件模块。
各系统模块功能如下:
1). 天气显示界面模块
显示指定城市三天内的天气状况,包括日期、城市名称、温度、风力与当日的建议,用户可通过按菜单键来显示菜单更新当前天气与设置天气显示的界面背景,以及跳转至设置预报城市界面来更换预报城市。
2). 预报城市设置模块
由自动设置预报城市与手动设置二部分组成,自动设置实现GPS 定位功能,自动确定当前用户所在地;而手动设置则通过可伸展性下拉列表单击选择系统数据
库中预存的城市来进行设置,同时为了方便用户查找,支持以输入框的形式来过滤查询预报城市。
当单击选中城市时跳转至天气显示界面,来显示该城市当三天内的天气状况;第一次运行时自动跳到该界面。
3). Widget 桌面小部件模块
为了方便用户实时了解天气状况,特别添加在Android 系统桌面上显示当前天气与时间的天气小部件,使用户拿起手机的第一时刻就能了解天气,同时当用户单击小部件时,自动跳转至天气显示界面,显示三天内的详细天气。
二、系统功能界面
1. 设置预报城市界面:
1.1 当第一次运行程序时,跳转至城市设置界面进行预报城市的选择:
1.2 用户可以通过单击选择“定位当前城市”的方式调用系统GPS 功能自动
定位预报城市:
1.3 用户可通过输入框过滤查询当前系统中预存的城市:
2.天气显示界面:
2.1 选择了预报城市后,系统跳转至天气显示界面,显示该城市三天内的实时天气:
2.2 在天气界面中用户可通过按菜单键来调出菜单,选择城市,更新天气与更换背景:
3.Widget桌面小部件界面:
方便用户第一时间了解天气动态,添加widget 显示功能界面:
三.设计目标
设计完成一个实用稳定的天气预报系统,同时要廉价使其能滿足大部分用户的需求,因此针对上述要求,本设计应滿足:
1.系统能及时的返反馈指定预报城市的天气情况
2.自动定位用户所在城市,支持GPS 定位
3.节省流量开销,规定在指定的时间间隔内才更新天气,其它时段显示缓
存的天气
4.操作方便快捷,使用简单,界面设计美观大方,支持widget
系统设计
一、开发及运行环境
JDK1.6.10
Eclipse3.5
Android Development Toolkit (ADT) 15.0.0
Android 2.2 及以上
Windows XP 及以上
二、数据库设计
由于在本系统中是通过中央气象台的WebService 提供的API 访问得到的天气预报,在查询指定城市的天气时,需要用到它提供的城市码,而城市码相对稳定不变,所以在构建系统时将其事先通过Android 的网络访问技术将其缓冲到本地SQLite 数据库进行保存起来,方便以后的查询,同时节省了流量开销。
综上所述在本地建立db_weather.db 的数据库,其中的表结构如下:
其中只存在两个表: provices 和citys
City 中存在city_num 用天气的查询,同时还存在外键province_id 与provices 表形成1 对n 的关系。
三、主要方法及步骤
1.搭建Android 开发环境,并建立一个android
2.2 版本名为WeatherSystem
项目
2.首先编写网络访问代码,访问/data5/city.xml 中央
气象站解析得到所有城市码并导出保存得到的db_weather.db 数据文件
3.在程序第一次运行时,将db_weatcher.db 数据库文件导入到应用程序数
据库中
4.建立设置城市界面,读取数据库文件,获取省份,城市以及对应的城市
码。
5.接收用户选择的城市码,访问:/data/<城市
码>.html 得到天气信息
6.解析天气信息,将城市码及天气信息缓冲下来,并为其设置有效时间,
方便下次启动时直接得到天气信息,过期则从网上更新
7.定时由保存的城市码更新天气信息
四、主要方法及技术
1.Android 手机的界面UI 设计
2.Android 的网络通信
3.Android 的广播
4.GPS 调用解析
5.Widget 小部件编程
6.XML 与JSON 解析
7.SQLite 数据库操作
8.Android 文件操作
主要模块
一、项目框架
在装有ADT 插件的Eclipse 中新建一个名为WeatherSystem 的Android2.2 版本的项目,项目主要文件结构如下:
WeatherSystem
|__src
| |_com.weather.app
| | |_MainActivity.java
| | |_SetCityActivity.java
| | |_UpdateWidgetService.java
| | |_WeatherWidget.java
| |_p
| | |_GPSListAdapter.java
| | |_MyListAdpater.java
| |_com.weather.dao
| | |_DBHelper.java
| |_com.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
二、主要功能实现
1.获取城市码db_weather.db数据库文件
获取全国各地的城市码,是通过访问中央气象局网从省份直辖市到城镇一
级
一级深入得到的,获得一个地区的城市码总共需要访问4 次网络,分别如下:
1. 访问/data5/city.xml 得到省份直辖市列表与它的编号:
2. 访问/data5/city<省份编号>.xml 得到该省份直辖市的城
市编号(如访问山东:/data5/city12.xml)
3. 访问/data5/city<城市编号>.xml 得到该城市的县区编号
(如访问济南:/data5/city1201.xml)
120101|济南,120102|长清,120103|商河,120104|章丘,120105|平阴,….
4. 访问/data5/city<县区编号>.xml 得到该县区的城市码(如
访问长清:/data5/city120102.xml)
120102|101120102
首先实现上述功能需使用Android 的网络访问技术,故编写工具类WebAccessTools 类如下:
由上面访问的可知,得到的编码与名称都是“编码|名称”的形式,因此在这也编写一个解析得到城市码的工具类WeatherInfoParser,用于解析从服务器中得到的城市码:
编写这两个类后现在就是编写从服务器端用程序遍历得到全国各地的城市名与城市码,并将它们分别的保存在String[][] provinces 数组,String[][] childs 数组与
String[][] cityCode 中:
接下来就是将得到的上面的三个数组建立数据库文件db_weather.db 保存起来,用到android.database.sqlite.SQLiteDatabase 类的静态方法:
SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory)来创建一个数据库文件,其中的path 表示数据库存放的路径,而factory 中游标工厂,这里可将它设为空,从而得到SQLiteDatabase 对象,则再调用它的execSQL(String sql)方法来执行保存数据库的操作,从而将上面的三个数组转换为数据库中的数据,最后使用ADT 插件中的DDMS工具将得到的数据库文件从Android 模拟器中导出,最终就得到了db_weather.db 文件。
以后上述的代码就可以不使用,直接将db_weather.db 文件放入资源文件夹res 目录中的raw 目录中,则在程序第一次运行时导入到/data/data/com.weather.app/databases 目录中就行了,其中关于数据库的导入实际是Java 中文件的复制。
2.实现可伸缩性列表的的构建与过滤
实现可伸缩性列表是通过继承android.widget.BaseExpandableListAdapter 适配器实现的,其中主要实现它的public View getGroupView()得列表的一级列表和public void getChildView()得到列表的二级子列表实现的,在这里由于只是实现文本显示功能,故用TextView 组件来填充就行了,如果要构造这个自定义的适配器,则只需在提供存放省份直辖市的一级列表的数组String[] groups 和存放对应的城镇的二级列表的String[][] childs 就行了。
同时为了兼具过滤功能,还要需再实现android.widget.Filterable 接口,这个接口有一个getFilter()返回Filter 过滤器的列表,故还要提供一个Filter 过滤类,在本系统中,实现的是一个内部类CityFilter,它继承android.widget.Filter 类,覆盖实现了两个方法,一个是performFiltering()得到FilterResults 过滤结果对象方法,另一个是根据得到的FilterResults 对象更新适配器的publishResults()方法。
其中的performFiltering(CharSequence constraint)方法的实现是通过constraint 这个关键字以省份直辖市为单位进行匹配,如果匹配成功,则添加该省份以下的所有城市,如果匹配不成功,则再逐一与这个省份的下的城市配匹,则只添加匹配的城市,其中匹配的结果放在Map<Integer, ArrayList<Integer>> values 这样的
向量中,再由新建的FilterResults 封装返回,(具体实现如下):
1.首先是对关键字进行判断是否为空,如为空则由values 添加所有省份与城
市,其中的allGroups 和allChilds 保存的是所有的省份与对应的城市:
2.如果关键字constraint 不为空,则以省份为单位进行匹配,省份匹配的添
加下面的所在城镇,如果不匹配,则进行步深入匹配城镇,添加符合条件
的城镇:
3.得到过滤的结果后将其用FilterResource 封装后返回:
另外的publishResults(CharSequence constraint, FilterResults results)方法就
是根据上面得到的results对象来得到新的String[] groups与String[][] Childs数组,再调用BaseExpandableListAdapter 父类的notifyDataSetChanged()方法来更新列表,从而实现过滤后结果的显示(具体实现如下):
1.首先将参数FiltersResuls 对象转换为Map<Integer, ArrayList<Integer>>
filterResult,然后来判断过滤后的结果长度时否为0,如果长度为0 则说明过滤后的结果为空,则调用父类的notifyDataSetInvalidated()方法来阻止列表的更新:
2.如果长度不为0,则说明存在过滤结果,则将它转换为groups 数组与
childs 数组,并调用notifyDataSetChanged()方法实再更新:
如上所述则就实现了带有过滤性可伸展性列表适配性的实现,则在使用时在XML 组件配置文件中使用ExpandableListView 列表,并调用它的setAdapter()方法
来,加载自定义的适配器。
而在使用它的过滤功能时则调用自定义适配器的getFilter()得到过滤Filter 对象,再调用Filter 对象的filter(String)方法实现的,在本系统中才用的时触发文本输入框EditText的TextChangedListener事件时调用从而实现手动选择预报城市的过滤查询。
3.GPS定位功能的实现
Android 中调用GPS 功能,首先要获取GPS 定位管理器LocationManager,获取LocationManager 后就是获取LocationProvider,可以通过Criteria 对象设置过滤
条件来获得最符合用户需求的LocationProvider,得到LocationProvider 后就可通
过调用LocationMananger 对象的getLastKnownLocation()方法来获取Location 地
址封装对象,最后由实例化的Geocoder 将Location 中的经度和纬度反编译为地
址信息集合List 对象,从而由List 对象来得到当前用户地址名。
在开发过程中
通过Eclipse 中的ADT 插件的DDMS 可以为Android 模拟器指定任意地址,如下:
当在模拟器控制面板中指定经纬度后,则会在模拟器中出现GPS 的标志:
但在实际开发调用GPS 功能过程时,只能获取经度与纬度,而在使用Geocoder
反编译地址时报错:
使用的调用代码如下:
后来通过网上搜索得知在Android2.2 模拟器中调用Geocoder 需要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.“
但并有说此服务要怎么得到,这看起来像是Android2.2 模拟器的一个Bug,故而在本设计中采用访问[/maps/geo?output=xml&q=经度,纬度]
的形式来得到详备的地址信息(来源于:/problems/69517),如下访问/maps/geo?output=xml&q=30.659269,104.065762:
其中的output 参数指定的是服务器响应的格式,除了XML 格式还可以为JSON,CSV 等格式。
由此可知,为了实现GPS 的定位功能还需要实现一个解析XML 的工具类,在
本系统中由工具类LocationXMParser 完成,它继承至org.xml.sax.helpers.DefaultHandler 类,用于专门用于解析XML 文件。
上述的GPS 功能具
体实现过程如下:
1.得到LocationManager 系统定位服务管理者:
2.设置Geocoder 对象,过滤得到符合条件的LocationProvider,再由
LocationProvider 得到封装经纬度信息的Location 对象:
3.得到经纬度后再访问/maps/geo 来得到含地址信息的
XML 文本内容,并用自定义的LocationXMParser 工具类解析封装得到此经纬度对应的城市名:
XML 中解析得到的国家、省份、县区和城市四个信息,在得到这些信息后,系统将与数据库中预存的省份城市相比较,最终匹配得到该地区的城市码完成GPS 自动定位功能的实现。
4.Widget窗体小部件的更新
由于widget 中的时钟关系,需要对widget 显示进行时刻的更新用来保持与系统中时间的一致。
实现这个功能需要用到AlarmManager 类,这个类专门用来设定在某个指定的时间去完成指定的事件。
设计思路是在Widget 的onUpdate 方法中启动一个自定义更新后台服务,更新widget,并设定下一分钟再次调用此服务。
具体实现过步骤如下:
1.首先自定义一个后台运行服务类继承至Service 类,实现它的服务开始运
行调用的onStart()方法:
2.然后在实现AppWidgetProvider 的widget 类的onUpdate 方法中启动这个
自定义的服务:
3.除了启动这个服务是不够的,当用户删除widget 部件时,后台服务也必
须停止,这样就必须实现Service 类中的另一个方法onDestroy()方法,该方法在Service 停止时调用,在这里用于取消AlarmManager 设置的警报服务:
4.则在widget类的onDisabled()方法中调用stopService方法来停止后台服
务, 其中的onDisabled 方法在widget 被用户删除时由系统自动调用:
在自定了一个Service 服务后,系统必须在清单文件AndroidManifest.xml 中声明自定义的服务:
这样就实现了widget 的更新功能,其实在配制widget 的AppWidgetProviderInfo 的配制文件中通过设置android:updatePeriodMillis 属性来设置widget 的自动更新,它的单位中毫秒,但由于自动更新对性能的损坏,故它有一个最低值,这最低值长于一分钟,故而与该系统的要求不符,故以调用后台Service 的方式来解决。
功能测试
本系统的的测试,主要是通过手动操作该系统,查看是否存在异常或操作的
结果是否符合设计初衷来完成的,现将系统的主要操作结果截图展示如下:
一.当系统初次启动时,由于没有设置预报城市,则自动由MianActivity 天
气显示视图跳转到SetCityActivity 城市设置视图,并要求用户选择预报
城市,如下:
二.接下来点击确定选择城市,则系统确定用户单击城市的城市码跳转至天
气显示界面,如下:
三.跳转到天气显示界面后,可单击“菜单”按钮来显示天气的菜单:
四.选择“壁纸”菜单项可以更换程序背景图片如下:
五.选择“设置城市”菜单项,则跳转至设置城市的视图界面,在这里可以
在输入城市的关键字在进行过滤查询,这样就及大的方便了用户的选择:
六.如果要定位当前的城市,以单击“定位当前城市”自动设置城市,而在
此之前必须,在DDMS控制面板中在指定一个经纬度,来开启GPS功能:
七.widget 窗体小部件的添加是通过长按桌面的空白处,出现一个选项菜单,
然后选择“窗体小部件”,接着在弹出的选项中选择“天气精灵”即本系统,则设计的小窗体部件将会出现在主屏幕的桌面上:
结论
本系统基本实现了需求的中的天气预报的功能,界面设计也较漂亮,具有一定的实用性。
其中的天气数据全部来源于网络,故在运行时一定要确保系统所处环境的网络流畅性。
由于开发过程是在Android2.2 版本的模拟器上运行的,故测试的结果可能存在一定的局性性。
同时在设计之初考虑问题的不全面,使得在无网状态下设计。