课程设计报告课程名称: 移动平台开发设计题目:空气质量查询院系:计算机科学与工程学院专业:计算机科学与技术班级:计科141学号:Z*********名:**指导教师:**设计地点:N6-113开课时间:2016 至2017 学年第1 学期目录1.引言 (1)1.1.题目描述 (1)1.2.设计意义 (1)2.开发环境 (1)2.1.硬件环境 (1)2.2.软件环境 (1)3.相关技术及知识点 (2)3.1.Activity (2)3.2.Service (2)3.3.网络通信 (3)4.需求分析 (3)4.1.系统功能需求分析 (3)4.2.系统流程图 (4)4.3.系统界面需求分析 (4)4.4.系统性能需求分析 (4)5.设计与实现 (5)5.1.界面布局 (5)5.2.省市二级联动 (6)5.3.获取空气质量数据 (9)5.4.播放背景音乐 (16)6.个人总结 (17)1.引言1.1.题目描述本次实验是开发一款基于Android平台的空气质量查询应用,将网络系统的功能扩展到智能手机终端上,让手机能够通过移动网络访问Web网站并处理各种各样的业务,可以让智能手机用户能够随时随地查询互联网所提供的空气质量信息。
1.2.设计意义可以让广大Android手机用户能够在第一时间获取最新的空气质量信息,以便提前预防,方便出行。
同时,把气象灾害造成的损失降到最低,也可以提高公共服务质量,更好的发挥气象事业对经济社会发展的现实性作用,有巨大的实用价值。
虽然该技术在Android平台已经比较成熟,但是通过该软件的开发仍然能帮助我更好的认识Android系统的工作原理。
2.开发环境2.1.硬件环境神州笔记本电脑2.2.软件环境Android的上层应用程序是用Java语言开发的,一般情况下是基于Dalvik虚拟机的,所以Google公司推荐使用主流的Java集成开发环境Eclipse。
而用Java语言进行开发,需要用到SUN 公司提供的Java SDK(其中包括JRE:Java Runtime Environment)。
此外,Android的应用程序开发和Java开发有较大区别的,需要使用Google提供的Android SDK。
同时,要在Eclipse 上安装ADT,为Android开发提供开发工具的升级或者变更,是Eclipse下开发工具的升级或下载的工具。
简言之,需要以下软件,才能搭建Android开发环境,从而进行Android应用程序的开发。
(1) Java SDK(2) Eclipse(3) Android SDK(4) ADT3.相关技术及知识点3.1.Activity应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。
Activity之间通过Intent进行通信。
在Intent 的描述结构中,有两个最重要的部分:动作和动作对应的数据。
典型的动作类型有:M AIN(activity的门户)、VIEW、PICK、EDIT 等。
而动作对应的数据则以URI 的形式进行表示。
例如:要查看一个人的联系方式,你需要创建一个动作类型为VIEW 的intent,以及一个表示这个人的URI。
与之有关系的一个类叫IntentFilter。
相对于intent 是一个有效的做某事的请求,一个intentfilter 则用于描述一个activity(或者IntentReceiver)能够操作哪些intent。
一个activity 如果要显示一个人的联系方式时,需要声明一个IntentFilter,这个IntentFilter 要知道怎么去处理VIEW 动作和表示一个人的URI。
IntentFilter 需要在AndroidManifest.xml 中定义。
通过解析各种intent,从一个屏幕导航到另一个屏幕是很简单的。
当向前导航时,activity 将会调用startActivity(Intent myIntent)方法。
然后,系统会在所有安装的应用程序中定义的IntentFilter 中查找,找到最匹配myIntent 的Intent 对应的activity。
新的activity 接收到myIntent 的通知后,开始运行。
当startActivity 方法被调用将触发解析myIntent 的动作,这个机制提供了两个关键好处:A、Activities 能够重复利用从其它组件中以Intent 的形式产生的一个请求;B、Activities 可以在任何时候被一个具有相同IntentFilter 的新的Activity 取代。
3.2.Service一个Service 是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序。
比较好的一个例子就是一个正在从播放列表中播放歌曲的媒体播放器。
在一个媒体播放器的应用中,应该会有多个activity,让使用者可以选择歌曲并播放歌曲。
然而,音乐重放这个功能并没有对应的activity,因为使用者当然会认为在导航到其它屏幕时音乐应该还在播放的。
在这个例子中,媒体播放器这个activity 会使用Context.startService()来启动一个service,从而可以在后台保持音乐的播放。
同时,系统也将保持这个service 一直执行,直到这个service 运行结束。
另外,我们还可以通过使用Context.bindService()方法,连接到一个service 上(如果这个service 还没有运行将启动它)。
当连接到一个service 之后,我们还可以service 提供的接口与它进行通讯。
拿媒体播放器这个例子来说,我们还可以进行暂停、重播等操作。
Service使用步骤如下:(1)继承service类;(2)AndroidManifast.xml配置清单文件中<application>节点里对服务进行配置<service name=".SMSService"/>。
服务不能自己运行,需要通过Contex.startService()或Contex.bindService()启动服务通过startService()方法启动的服务于调用者没有关系,即使调用者关闭了,服务仍然运行想停止服务要调用Context.stopService(),此时系统会调用onDestory(),使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onStart(),如果服务已经启动再次调用只会触发onStart()方法。
使用bindService()启动的服务与调用者绑定,只要调用者关闭服务就终止,使用此方法启动时,服务首次启动系统先调用服务的onCreate()-->onBind(),如果服务已经启动再次调用不会再触发这2个方法,调用者退出时系统会调用服务的onUnbind()-->onDestory(),想主动解除绑定可使用Contex.unbindService(),系统依次调用onUnbind()-->onDestory()。
3.3.网络通信JSON数据解析:(1)JavaScript Object Notation是一种轻量级的数据交换格式;(2)Android API中直接支持对JSON数据的处理;(3)常用类JSONObject、JSONArray、JSONStringer和JSONTokener等;(4)数据在名称/值对中、数据由逗号分隔、花括号保存对象、方括号保存数组。
HttpURLConnection:提供了基于HTTP的网络访问方法,主要的操作步骤为:(1)利用URL地址实例化URL类;(2)由URL类创建HttpURLConnection对象;(3)以GET/POST方式向服务器发送请求;(4)接收服务器响应。
4.需求分析4.1.系统功能需求分析(1)能够由用户设置省份城市;(2)根据用户设置的城市,点击刷新按钮获取当地当天的日期、天气信息以及未来六天的天气情况。
(3)以淡入淡出的方式显示主页面;(4)打开软件时可以自动播放音乐,用户可以在Menu菜单里选择关闭音乐;(5)Menu菜单里可以查看开发者信息。
4.2.系统流程图图4-1 系统流程图4.3.系统界面需求分析目前国内软件开发者在设计过程中很注重软件的开发技术及其具有的业务功能,而忽略了用户对软件界面的需求,影响软件的易用性、友好性。
界面设计要简约、美观,不能太复杂,让用户操作起来太繁琐,影响用户的使用体验,要在交互性与应用性上让用户感到舒适,让用户准确、高效、轻松、愉快地完成空气质量的查询,所以软件的友好性、易用性对软件系统至关重要。
4.4.系统性能需求分析软件在完成功能需求之后,还要进一步的优化,不能占用手机太多的内存资源,在交互性上使用户获得最佳感受,让使用不同手机设备的用户都能有良好地体验。
5.设计与实现5.1.界面布局在页面的布局上,因为界面设计的比较简单,所以只使用了基础的横向布局和纵向布局,横向布局与纵向布局交替使用,完成了空气质量查询的界面设计。
图5-1 界面布局图5-2 软件主界面图5-3 启动界面图5-4 空气质量信息界面图5-5 音乐界面图5-6 作者信息界面5.2.省市二级联动将老师给的中国省市的编号手动输入到strings.xml文件中,再定义省份和城市编号两个数组,再定义ArrayAdapter,在两个下拉框上分别放上监听器,将省份与城市进行绑定,将所选择的城市的城市编号存放到一个数组之中,以便之后进行空气质量信息的获取。
关键代码:private int[] cities = { R.array.beijing, R.array.tianjin,R.array.hebei,R.array.shanxi1, R.array.neimenggu, R.array.liaoning, R.array.jilin, R.array.heilongjiang,R.array.shanghai,R.array.jiangsu, R.array.zhejiang, R.array.anhui, R.array.fujian,R.array.jiangxi,R.array.shandong, R.array.henan, R.array.hubei,R.array.hunan,R.array.guangdong, R.array.guangxi, R.array.hainan,R.array.chongqing, R.array.sichuan, R.array.guizhou,R.array.yunnan, R.array.xizang,R.array.shanxi3, R.array.gansu,R.array.qinghai, R.array.ningxia,R.array.xinjiang, R.array.taiwan,R.array.xianggang };private int[] citycode = { R.array.bei_jing, R.array.tian_jin,R.array.he_bei, R.array.shan_xi1, R.array.nei_meng_gu,R.array.liao_ning, R.array.ji_lin, R.array.hei_long_jiang,R.array.shang_hai, R.array.jiang_su, R.array.zhe_jiang,R.array.an_hui, R.array.fu_jian, R.array.jiang_xi,R.array.shan_dong, R.array.he_nan, R.array.hu_bei, R.array.hu_nan, R.array.guang_dong, R.array.guang_xi, R.array.hai_nan,R.array.chong_qing, R.array.si_chuan, R.array.gui_zhou,R.array.yun_nan, R.array.xi_zang, R.array.shan_xi3, R.array.gan_su, R.array.qing_hai, R.array.ning_xia,R.array.xin_jiang,R.array.tai_wan, R.array.xiang_gang };img1.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubAlertDialog.Builder builder = new AlertDialog.Builder(WeatherActivity.this);builder.setTitle("请选择所属城市");View v1 =LayoutInflater.from(WeatherActivity.this).inflate(yout.activity_cities, null);sp1 = (Spinner) v1.findViewById(R.id.spinner1);sp2 = (Spinner) v1.findViewById(R.id.spinner2);sp1.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> parent,View view, int position, long id) {// TODO Auto-generated method stubadapter = ArrayAdapter.createFromResource(WeatherActivity.this, cities[position], yout.select_dialog_singlechoice);sp2.setAdapter(adapter);cit =getResources().getStringArray(citycode[position]);}@Overridepublic void onNothingSelected(AdapterView<?> parent) {// TODO Auto-generated method stub}});sp2.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> parent,View view, int position, long id) {// TODO Auto-generated method stubst1=cit[position];}@Overridepublic void onNothingSelected(AdapterView<?> parent) {// TODO Auto-generated method stub}});builder.setView(v1);builder.setPositiveButton("确定",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {// TODO Auto-generated method stubwea_city.setText(sp2.getSelectedItem().toString());cityId = st1;ed.putString("city",wea_city.getText().toString());ed.putString("citycode", cityId);mit();refresh();}});builder.setNegativeButton("取消", null);AlertDialog dialog = builder.create();dialog.show();}});图5-7 选择省份图5-8 选择城市5.3.获取空气质量数据获取空气质量信息主要使用的是HttpURLConnection类,提供了基于HTTP的网络访问方法,由URL类创建HttpURLConnection对象,以GET/POST方式向服务器发送请求,接收服务器响应,最后通过JSON数据解析,将解析得到数据绑定到相应的组件中。