版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、信息工程学院本科生毕业设计说明书题目:基于Android的天气短信系统的设计与实现 姓 名: 丁柏林 学 号: 2011110262 专 业: 计算机科学与技术 班 级: 11计科2班 指 导 教 师: 房爱东 目 录1 系统概述11.1 设计目的11.2 设计思路11.3系统需求分析11.4开发环境21.4.1 Android开发环境的介绍21.4.2 Android的开发平台搭建21.5 运行环境31.6 参考文献32.总体设计42.1系统结构42.1.1 系统流程图42.1.2 模块结构图42.2数据库的设计52.3 模块功能设计62.3.1 获取当前天气功能62.3.2 选择城市的功能
2、62.3.3 发送短信的功能63.运行设计73.1用户界面设计73.2 运行代码94.系统测试254.1功能性测试254.2 稳定性测试274.3 安全性测试275 结论282015届本科生毕业设计说明书 系统概述1 系统概述 近几年来随着3G 技术成熟和智能手机的不断普及,移动应用的需求与日俱增,移动应用开发成为当下最热门的技术之一。在Google和Android 手机联盟的共同推动下,Android在众多移动应用开发平台中脱颖而出。Android是一个真正意义上的开源智能手机操作系统,该系统一经推出立即受到全球移动设备厂商和开发者的热捧。为顺应潮流,本设计旨在搭载 Android 的移动设
3、备上运行,实现天气状况的实时动态更新与显示,并将显示的天气可以发短信给指定的联系人。1.1 设计目的 天气软件是一种非常实用的信息服务,随着智能手机的不断普及,各种智能手机平台下都有各种各样的天气软件。Android作为现在主流的智能手机之一,自然也需要这方面的软件。天气关系到人们的日常生活,如告知温暖,方便出行等。此外,对未来天气的预测你还可以指定发短信给家里不会上网的父母,帮助父母进行农作物的浇灌、施肥、收割等工作。1.2 设计思路天气短信这个设计不算复杂,我先在eclipse里面把系统的主界面写好,然后先是联网解析从360天气预报端口读取来的数据,数据解析完了在本地创建数据库,把联网解析
4、的数据保存在本地,减少流量的使用。之后就是选择想要的城市来获取当前城市未来的天气情况,并把天气情况编辑成样例短信,最后选择联系人在指定的时间发送短信,最后就是短信发送成功之后会提醒的消息推送通知。1.3系统需求分析本软件是一个基于Android的应用程序,启动程序后可以进行城市的选择设置,可以通过文字显示当前和未来的天气状况,包括温度、湿度、风向和雨雪情况等。这些天气数据是通过后台服务获取的,这个后台服务可以按照一定时间间隔,从360上获取天气预报信息,并将天气信息保存在数据库中。可以选定指定的联系人并且设置指定的时间发送天气短信给对方。从上面的描述中可以基本了解软件的功能需求:(1) 启动A
5、ndroid的应用程序;(2) 设置界面:对要显示天气预报的城市进行设置;(3) 显示界面:通过文字显示当前的天气情况,包括日期、时间、城市、最高温度、最低温度、当前温度等。而且可以选定指定的联系人在指定的时间发送天气短信给对方。1.4开发环境1.4.1 Android开发环境的介绍Android平台使用Java编程语言来开发应用程序,而Android提供了对Java的核心支持。考虑到Java虚拟机的执行效率和占用资源情况,Google重新设计了Java的编译器,命名为Dalvik。Dalvik是经过优化的Java编译器,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik应用作
6、为一个独立的Linux进程执行,独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。项目的开发在Eclipse环境中进行,由于进行的是Android应用程序的开发,需要在Eclipse安装ADT插件,即Android开发工具,这样Eclipse就可以和Android SDK建立连接,在Eclipse中启动Android模拟器、调试程序等工作。由以上分析可知,Android平台的搭建需要Android SDK、Java SDK、Eclipse和ADT四个软件。1.4.2 Android的开发平台搭建在进行Android应用程序的开发前,要先搭建Android平台,然后才能在开发环境中进行编程。
7、根据官方指导,对Android平台的搭建过程介绍如下:首先,在官方网址上下载JDK6.0并安装,网址是然后,在官方网址上下载更新的SDK进行安装,官方网址为 Manager进行安装,选择需要的Android版本,然后更新,这次更新需要的时间比较慢,所以更新前要做好准备。安装完成后,将ADB命令所在的目录platform-tools的完整路径添加到系统的环境变量PATH中,就能够在命令中使用ADB命令了;接下来要安装的是ADT插件,即Android开发工具。因为ADT在线安装容易遇到问题,增加一些不必要的麻烦所以需要下载后在本地安装。指定网址为最后,下载Eclipse,建议选择Eclipse3.
8、4以上版本,网址为/downloads/,解压到指定位置后运行。选择Eclipse菜单中的Help>Install New Software选项卡上的Available Software,点击右侧的Add,然后在Name框中填写Android,在Location框中选择上步下载的ADT文件,然后点击OK>Finish>Install All,这时关闭Eclipse再重新启动。重启后选择Eclipse菜单中的Window>Preferences,在左侧的Android项目中SDK Location中填入Android SDK解压后
9、的目录,然后点击Apply。这样,整个平台的搭建工作就完成了。1.5 运行环境运行需要Android SDK、Java JDK、Eclipse和ADT四个软件,以及Android2.2的虚拟机或者真机,操作系统为Windows7的PC机一台1.6 参考文献1 王向辉,张国印,沈洁. Android应用程序开发M.北京:清华大学出版社,20122 李刚. 疯狂Android讲义M. 北京:电子工业出版社,20133 明日科技. Android从入门到精通M. 北京:清华大学出版社,20124 李刚. 疯狂Java讲义M. 北京:电子工业出版社,20135 Y.Daniel Liang. Java
10、语言程序设计(李娜) M. 北京:机械工业出版社,20116 邓凡平. 深入理解AndroidM. 北京:机械工业出版社,20117 马超,孙仁贵. Android应用开发全程实录M. 北京:人民邮电出版社,20128 刘昌平,范明钰.Android手机的轻量级访问控制J.计算机应用研究,2010,7:201-212.9 张仕成.基于Google Android平台的应用程序开发与研究J.电脑知识与技术,2009:35-59.10 杨丰盛.Android应用开发揭秘M.北京:机械工业出版社,2010282015届本科生毕业设计说明书 总体设计2.总体设计2.1系统结构2.1.1 系统流程图本系
11、统的流程是当我们在桌面上打开软件时进入到用户的主界面,进入主界面后第一次是会让我们选择城市,我们点击城市的下拉列表选中自己想要查询的城市,在我们的短信中会出现该城市的天气并生成样列短信,最后我们设置指定的联系人并设置指定的时间发送短信到指定的联系人,当短信发送成功后我们会收到来自通知栏的消息告诉我们短信已经发送成功。图2-1系统流程图2.1.2 模块结构图后台服务App启动 App启动服务 用户界面 设置相关信息天气信息 startService(new Intent)启动服务数据库获取模块360天气预报服务设置联系人和发送时间SQLite数据库获取模块发送短信并返回发送成功的通知图2-2模块
12、结构图2.2数据库的设计由于在本系统中是通过中央气象台的WebService 提供的API访问得到的天气预报,在查询指定城市的天气时,需要用到它提供的城市码,而城市码相对稳定不变,所以在构建系统时将其事先通过Android的网络访问技术将其缓冲到本地SQLite数据库进行保存起来,方便以后的查询,同时节省了流量开销。综上所述在本地建立db_weather.db的数据库,其中的表结构如下:图2-3数据库表结构其中只存在两个表: provices 和citys City 中存在city_num用天气的查询,同时还存在外键province_id与provices表形成1对n的关系。2.3 模块功能设
13、计2.3.1 获取当前天气功能显示指定城市三天内的天气状况,包括日期、城市名称、温度、风力,用户可通过选择城市来获取城市天气,并且可以把天气编辑成短信。2.3.2 选择城市的功能通过手动选择可伸展性下拉列表单击选择系统数据库中预存的城市来进行设置,同时为了方便用户查找,当单击选中城市时跳转至天气显示界面,来显示该城市当三天内的天气状况。2.3.3 发送短信的功能为了使用户能够选择指定的联系人,在界面上加上了选择联系人的输入框,并且还有时间选择,是用户能够设置在指定的时间发送短信给指定的人。2015届本科生毕业设计说明书 运行设计3.运行设计3.1用户界面设计根据需求分析可以知道,应用程序应包含
14、三个主要的功能,这里需要进一步分析每个功能中应该具体怎样实现。在获取网络上的天气服务时应该做到读取未来三天的天气,并把天气转为短信内容示例。当然我们可以选择当前城市的信息,设置省市联动的效果,并且我们可以设置指定联系人的信息和在什么时间发送短信。根据以上的功能分析得到以下的用户界面图:图3-1主界面布局图3-2用户主界面图3-3选择省份图3-4选择城市3.2 运行代码根据天气预报系统功能需求分析,系统启动后,应在主界面上呈现出,默认城市的天气数据,因此需要创建主界面和解析天气的类,包括获取、解析城市天气数据,并在用户界面上呈现出来。为此,需要解决的问题是手机终端从Web 服务器获取了
15、所有类型的数据之后,将这些数据进一步交给Android 手机终端View 组件,在手机界面上显示给用户。联网获取天气情况并把天气情况变为样例短信。主要是通过360天气预报的端口从网络上解析数据,并把数据保存到本地的数据库中,在从数据库中调取所需城市的天气,并把天气转为示例代码:/重写callable接口中的方法callSuppressLint("SimpleDateFormat") Overridepublic String call() throws Exception try /这里使用的是360天气预报,比较几个之后,发现这个比较靠谱/url最后的
16、101010100 是指北京,在/联网读取天气数据/创建连网使用的客户端连接类httpclient,以及本次请求的封装对象httpgetHttpGet httpGet = new HttpGet("HttpClient httpClient = new DefaultHttpClient();/执行请求并获取服务器的响应HttpResponse httpResponse = httpClient.execute(httpGet);/获取http的响应码,判断本次连接是否成功if (httpResponse.getStatusLine().getStatusCode() = HttpS
17、tatus.SC_OK) /获取响应数据的字符串内容并针对字符串进行拆分String unicodeResult = EntityUtils.toString(httpResponse.getEntity().split("(")1.split(")")0;/ unicode解码后获取各节点的值/ 获取市/System.out.println(unescapeUnicode(unicodeResult);timestamp=(new JSONObject(unicodeResult).getLong("time");/System.o
18、ut.println(timestamp);/通过stringbuffer实现字符串的拼接weatherMsg.append(new JSONObject(unicodeResult).getJSONArray("area").getString(2).split(""")1).append("");JSONArray jsonArray = new JSONObject(unicodeResult).getJSONArray("weather");for (int i = 0; i < jsonA
19、rray.length(); i+) JSONObject jsonDay = jsonArray.getJSONObject(i);/ 获取日期 几月几日weatherMsg.append(sdf2.format(sdf.parse(jsonDay.getString("date");JSONObject jsonInfo = jsonDay.getJSONObject("info");String dayInfo = jsonInfo.getString("day").split(""");Strin
20、g nightInfo = jsonInfo.getString("night").split(""");if (dayInfo3.equals(nightInfo3) weatherMsg.append(dayInfo3).append("#"); else weatherMsg.append(dayInfo3).append("转").append(nightInfo3).append("#");if (!(dayInfo9.equals("微风") if (d
21、ayInfo7.equals(nightInfo7) weatherMsg.append(dayInfo7);if (dayInfo9.equals(nightInfo9) weatherMsg.append(dayInfo9).append("#"); else weatherMsg.append("白天").append(dayInfo9);weatherMsg.append("夜间").append(nightInfo9).append("#"); else weatherMsg.append("白
22、天").append(dayInfo7).append(dayInfo9).append("#");if (!(nightInfo9.equals("微风") weatherMsg.append("夜间").append(nightInfo7).append(nightInfo9).append("#"); else if (!(nightInfo9.equals("微风") weatherMsg.append("夜间").append(nightInfo7).ap
23、pend(nightInfo9).append("#");weatherMsg.append(nightInfo5).append("").append(dayInfo5).append("度;");weather = weatherMsg.substring(0, weatherMsg.length() - 1);weathers = weather.split("");/将weathers数组转成集合后,toString再转成字符串weather = Arrays.asList(weathers).toStri
24、ng(); / 4 dayfor(int i=0;weather.length()>70;i+)System.out.println(weather.length();/将数据转成集合,然后通过sublist方法截取集合中的部分内容后,将截取后的集合toString的到字符串weather = Arrays.asList(weathers).subList(0, Arrays.asList(weathers).size()-i).toString();/针对字符串进行字符的替换weather = weather.replace("", "").re
25、place("", "").replace(" ", "").replace(",", "").replace("#", ",");/String date = new java.text.SimpleDateFormat("HH:mm").format(new java.util.Date(timestamp * 1000);/weather = weather + "" + date + &q
26、uot;发布"return weather; catch (Exception e) e.printStackTrace();return null;public String unescapeUnicode(String str) StringBuffer sb=new StringBuffer(); /将字符串根据制定的正则表达式进行匹配(可简单的理解为将特殊的字符串根据指定的方式进行拼配后替换) Matcher matcher = Ppile("u(0-9a-fA-F4)").matcher(str); while(matcher.find() /如果字符串
27、中包含指定字符 /则对字符串进行退换操作 matcher.appendReplacement(sb, (char)Integer.parseInt(matcher.group(1),16)+""); matcher.appendTail(sb); return sb.toString().replace("", "");/顺便去掉上面的转义字符"" 根据天去短信系统的需求分析,选择城市并获取天气的类,通过连接本地的SQLite数据库根据城市的城市码来到本地的数据库中找到并把天气显示在用户的界面上,具体实现代码如下:
28、 public void initSpinner1()dbm = new DBManager(this); dbm.openDatabase(); db = dbm.getDatabase();/获取数据库对象 List<MyListItem> list = new ArrayList<MyListItem>(); try String sql = "select * from provinces" /查询数据库中的provinces表中的数据 Cursor cursor = db.rawQuery(sql,null); cursor.moveToF
29、irst(); /如果有多行数据,就循环读取表中每一行的数据 while (!cursor.isLast() /获取表中列名为_id的列中当前行的值 String code=cursor.getString(cursor.getColumnIndex("_id"); System.out.println("initSpinner1"+code); /获取表中第二列中当前行的数据值 byte bytes=cursor.getBlob(1); String name=new String(bytes,"utf-8"); /初始化列表中每个
30、item中要显示的数据封装类对象 MyListItem myListItem=new MyListItem(); myListItem.setName(name); myListItem.setPcode(code); list.add(myListItem); /让游标移动到下一行 cursor.moveToNext(); /如果没有多行数据,那么就读取当前行的数据 String code=cursor.getString(cursor.getColumnIndex("_id"); byte bytes=cursor.getBlob(1); String name=new
31、 String(bytes,"utf-8"); MyListItem myListItem=new MyListItem(); myListItem.setName(name); myListItem.setPcode(code); list.add(myListItem); catch (Exception e) MyAdapter myAdapter = new MyAdapter(this,list); spinner1.setAdapter(myAdapter); String sql = "select province_id from citys wh
32、ere city_num='"+areaCode+"'" /查询数据库中指定城市的province_id Cursor cursor = db.rawQuery(sql,null); cursor.moveToFirst();/将游标移动到表中第一行 spinner1.setSelection(cursor.getInt(0), true);/设置spinner默认选项 /设置spinner的选择事件spinner1.setOnItemSelectedListener(new SpinnerOnSelectedListener1();/关闭数据库d
33、bm.closeDatabase(); db.close(); String pcode = String.valueOf(cursor.getInt(0)+1); initSpinner2(pcode); public void initSpinner2(String pcode)dbm = new DBManager(this); dbm.openDatabase(); db = dbm.getDatabase(); List<MyListItem> list = new ArrayList<MyListItem>(); String dstName="&
34、quot; int idx=0; int found=0; String sql = "select name from citys where city_num='"+areaCode+"'" /查询指定城市的城市名 Cursor cursor = db.rawQuery(sql,null); cursor.moveToFirst(); byte bytes=cursor.getBlob(0); try dstName = new String(bytes,"utf-8"); catch (UnsupportedEn
35、codingException e) / TODO Auto-generated catch block e.printStackTrace(); pcode = String.valueOf(Integer.valueOf(pcode).intValue() - 1); try String sql = "select * from citys where province_id='"+pcode+"'" /查询表中指定省份所有城市的城市信息 Cursor cursor = db.rawQuery(sql,null); cursor.m
36、oveToFirst(); while (!cursor.isLast() String code=cursor.getString(cursor.getColumnIndex("_id"); byte bytes=cursor.getBlob(2); String name=new String(bytes,"utf-8"); String city_num = cursor.getString(cursor.getColumnIndex("city_num"); if(0=found) if(!dstName.equals(nam
37、e) idx += 1; else found=1; MyListItem myListItem=new MyListItem(); myListItem.setName(name); myListItem.setPcode(code); myListItem.setCityNum(city_num); list.add(myListItem); cursor.moveToNext(); String code=cursor.getString(cursor.getColumnIndex("_id"); byte bytes=cursor.getBlob(2); Strin
38、g name=new String(bytes,"utf-8"); String city_num = cursor.getString(cursor.getColumnIndex("city_num"); MyListItem myListItem=new MyListItem(); myListItem.setName(name); myListItem.setPcode(code); myListItem.setCityNum(city_num); list.add(myListItem); catch (Exception e) MyAdapte
39、r myAdapter = new MyAdapter(this,list); spinner2.setAdapter(myAdapter); spinner2.setSelection(idx, true);spinner2.setOnItemSelectedListener(new SpinnerOnSelectedListener2(); dbm.closeDatabase(); db.close();class SpinnerOnSelectedListener1 implements OnItemSelectedListenerpublic void onItemSelected(A
40、dapterView<?> adapterView, View view, int position,long id) /获取spinner选择的item选项String pcode =(MyListItem) adapterView.getItemAtPosition(position).getPcode();initSpinner2(pcode);public void onNothingSelected(AdapterView<?> adapterView) / TODO Auto-generated method stubclass SpinnerOnSelec
41、tedListener2 implements OnItemSelectedListenerpublic void onItemSelected(AdapterView<?> adapterView, View view, int position,long id) String city_num =(MyListItem) adapterView.getItemAtPosition(position).getCityNum();areaCode = city_num;public void onNothingSelected(AdapterView<?> adapte
42、rView) / TODO Auto-generated method stub/设置点击菜单键时的显示内容 Override public boolean onCreateOptionsMenu(Menu menu) / Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; /设置菜单选项选中时的事件监听 Override public boolean onOptionsItemSelect
43、ed(MenuItem item) / Handle action bar item clicks here. The action bar will / automatically handle clicks on the Home/Up button, so long / as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id = R.id.action_settings) String info="作者:丁柏林nE-MAIL:1183084407&quo
44、t; new AlertDialog.Builder(MainActivity.this).setTitle("关于").setMessage(info).setPositiveButton("确定", null).show(); return true; return super.onOptionsItemSelected(item); 获取天气后生成短信,以下代码实现了怎样发送短信的功能:public class SendSms /* * 以下代码均为实现发送短信的代码 * */SmsManager smsManager = SmsManager.g
45、etDefault();public boolean sendMessage(String phoneCode, String content,PendingIntent sentIntent) if (content.length() > 70) List<String> weatherList = smsManager.divideMessage(content);for (String str : weatherList) smsManager.sendTextMessage(phoneCode, null, str, sentIntent,null); else sm
46、sManager.sendTextMessage(phoneCode, null, content, sentIntent,null);return false;存储和读取文件的类:public class DataFile private Context context;final private String FILE_NAME="weather.dat"public DataFile(Context context) this.context = context;/存储数据到文件public void saveData(String data) throws Exce
47、ption/context.getFilesDir();/ 得到存放文件的系统目录 /data/data/<package name>/files/context.getCacheDir(); /缓存目录 /data/data/<package name>/cache/*获取文件输出流,方便将数据写入指定文件中*/FileOutputStream outputStream=context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);/写入数据outputStream.write(data.getBytes();/关闭流
48、outputStream.close();/ 读取数据public String getData() throws Exception/获取指定文件的输入流,文件存储位置:/data/data/<package name>/files/FILE_NAMEFileInputStream inputStream=context.openFileInput(FILE_NAME);/得到缓存输出流对象ByteArrayOutputStream outStream=new ByteArrayOutputStream();byte buffer=new byte1024;int len=0;w
49、hile (len=inputStream.read(buffer)!=-1)/将读取的内容写入缓存输出流中outStream.write(buffer, 0, len);outStream.close();/得到输出流中的数据byte数组byte data=outStream.toByteArray();/讲数组转成字符串并返回String name=new String(data);return name;数据库的管理类:public class DBManager private final int BUFFER_SIZE = 1024; public static final String DB_NAME = "city_cn.s3db" public static final String PACKAGE_NAME = "com.example.weathertest" /定义数据库文件存储路径:data/data/程序包名 public
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论