源码以及文档下载  https://me.csdn.net/download/qq_27500493

计算机学院2014级学年论文   LZL 于  2017 年  8 月  29 日

完 美 天 气 A P P

内容摘要  在智能手机中,Android平台约占75%市场份额。安卓系统的广泛应用,使得Android手机应用程序的数量快速增长。Android APP也逐渐成为人们生活不可或缺的一部分。本设计开发了一种运用在Android系统上的手机天气预报软件系统,本系统通过选择城市来获得天气,风向,温度,生活健康提示等信息,以及备忘录日历等功能。基于手机的该软件极大的方便了用户的出行和行程安排,避免了不必要的麻烦,具有很强的实用性。

关键词  Android,天气预报APP,完美天气

1.1 章   需 求 分 析

1.1.1  开发背景

随着智能手机的不断普及,移动应用开发成为当下最热门的技术之一。在 Google 和 Android 手机联盟的共同推动下,Android 在众多移动应用开发平台中脱颖而出。Android 是一个真正意义上的开源智能手机操作系统,该系统一经推出立即受到全球移动设备厂商和开发者的热捧。为顺应潮流,本设计旨在搭载 Android 的移动设备上运行,方便用户的出行和行程安排。

1.1.2 项目需求分析

根据功能的需求,主要功能应具备如下几点:

1.   定位查询全国各地城市未来几天内的天气状况

2.   给出实时的出行建议和生活指数建议

3.   系统要实现三级联动查询城市

4.  系统实现备忘录和日历功能

2.1 章   总 体 设 计

2.1.1  系统规划

由上述的需求,现将系统分为三大模块:天气显示模块、城市切换模块、日历模块与备忘录模块。各系统模块功能如下:

1). 天气显示模块

显示指定城市三天内的天气状况,包括时间、城市名称、温度、湿度、风力与当日的各项指数,用户可通过按定位键来进行定位显示当前城市相关指数,以及跳转至设置预报城市界面来更换城市。

2). 预报城市设置模块

由自动设置预报城市与手动设置二部分组成,自动设置实现 GPS 定位功能,自动确定当前用户所在地;而手动设置则通过三级联动选择省,城市,地区。

3). 备忘录日历模块

进入日历模块以后,可以查看相应的日历。点击相应日历可以添加对应的备忘录事件,也可以进入单独备忘录列表进行管理备忘录

2.1.2  功能界面

    

    

3.1 章   系 统 设 计

3.1.1  开发及运行环境

JDK1.6                    adt-bundle-windows-x86_64-20130219

SDK17                      夜神模拟器Android4.4.2

3.1.2   数据库设计

两张表:

CITY表 存放城市信息,用于保存最近一次使用的城市信息,下次打开APP直接显示该城市对应信息。

MEMEORY表 备忘录表 存放备忘录内容 时间

3.1.3  主要流程

1. 搭建相应Android环境,建立命名为pfweather项目

2. 进入welcome欢迎界面

3. 程序首次运行,建立相应数据库和表,将默认城市呼和浩特进行显示

4.城市选择界面,解析city.JSON 获取相应的省份,城市,地区对应关系

5. 若选择定位,则调用高德API进行定位并将城市名字传入天气API串

6. 将城市名字传入和风天气对应API串中,进行请求返回对应JSON串进行解析显示到对应控件上

7.若打开日历备忘录界面,则前台进行操作对应后台数据库进行增删查改。

3.1.4  主要方法技术

1.    Android界面 UI 设计 2.     Android 的网络通信

3.    Android 的广播机制 4. 高德API的调用实现定位

5.    JSON 手动解析 与 GSON工具解析

6.    SQLite 数据库相应操作 7.  调用和风天气API获取天气数据

4.1 章   具 体 实 现

4.1.1  项目结构

4.1.2  主要功能实现

4.1.2.1 手动解析JSON 获取城市列表

先将Json串转为String串/ 初始化读取city.json为Stringprivate String initData() {StringBuffer sb = new StringBuffer();AssetManager assetmanager = this.getAssets();try {InputStream is = assetmanager.open("city.json");byte[] data = new byte[is.available()];int len = -1;while ((len = is.read(data)) != -1) {sb.append(new String(data, 0, len, "gb2312"));}is.close();return sb.toString();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}

再手动解析JSON


JSONObject object = new JSONObject(cityJson);JSONArray array = object.getJSONArray("citylist");sprovience = new String[array.length()];String mprovience = null;for (int i = 0; i < array.length(); i++) {JSONObject mProvienceObject = array.getJSONObject(i);if (mProvienceObject.has("p")) {mprovience =mProvienceObject.getString("p");//取省份具体值provience[i] = mprovience;} else {sprovience[i] = "未知地点";}

其他类似,逐层解析出省份,城市,地区并存在对应String数组中

通过Map将省-市;市-区 进行关联;利用Spinner 将对应信息绑定显示

    // 存省对应的所有市private Map<String, String[]> mCitiesDataMap = new HashMap<String, String[]>();// 存市对应的所有区private Map<String, String[]> mAreaDataMap = new HashMap<String, String[]>();mAreaDataMap.put(mcity, sarea);mCitiesDataMap.put(mprovience, scity);

4.1.2.2 天气实体类获取

    Weather实体类的获取:此处传入城市名字,通过从网上请求下载对应Json串转为String串之后进行操作// 通过城市获取对应Weather实体类public static Weather UpdateWeather(String city) {String cname; String MyKey = "6130363df20b4d1ea928bb07257ace9a";cname = URLEncoder.encode(city, "utf-8");String url = "https://free-api.heweather.com/v5/weather?city="+ cname + "&key=" + MyKey;  String jsonStr = UpdateUtil.getWeString(url);JsonParser parse = new JsonParser();JsonObject jsonObject = (JsonObject) parse.parse(jsonStr);JsonArray heWeather = jsonObject.get("HeWeather5").getAsJsonArray();if (heWeather.size() == 0) {return null;} else {String weatherStr = heWeather.get(0).toString();Weather weather = new Gson().fromJson(weatherStr, Weather.class);return weather;
因为用到网络通信,所以需要新起一个线程利用handle进行传递消息Handler handler = new Handler() {public void handleMessage(Message msg) {super.handleMessage(msg);Bundle data = msg.getData();Weather w = (Weather) data.getSerializable("value");citydb.city_insert(cname); updateView(w); }};Runnable runnable = new Runnable() {public void run() {Message msg = new Message();Bundle data = new Bundle();data.putSerializable("value", UpdateUtil.UpdateWeather(cname));msg.setData(data); handler.sendMessage(msg); }};

4.1.2.3 定位模块实现

 调用高德API  首先在AndroidMainfest中定义相关权限和KEY<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><uses-permission android:name="android.permission.WAKE_LOCK" /></meta-data><service android:name="com.amap.api.location.APSService"></service>//初始化定位函数public void initlocate() {// 启动定位mLocationClient = new AMapLocationClient(getApplicationContext());mLocationClient.setLocationListener(this);AMapLocationClientOption mLocationOption = new AMapLocationClientOption();mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);mLocationOption.setInterval(2000);mLocationOption.setOnceLocation(true);mLocationClient.setLocationOption(mLocationOption);mLocationClient.startLocation();}//定位回调函数,手动进行实现public void onLocationChanged(AMapLocation location) {cname = location.getCity();new Thread(runnable).start();Weather newweather = UpdateUtil.UpdateWeather(location.getCity());updateView(newweather);mLocationClient.stopLocation();}

4.1.2.4 每次打开APP展示最近选择城市

Handler handler = new Handler() {public void handleMessage(Message msg) {super.handleMessage(msg); Bundle data = msg.getData();Weather w = (Weather) data.getSerializable("value");citydb.city_insert(cname); updateView(w);}};

每次更新城市时候将名字传入数据库中    打开APP时候 从数据库表中取得最近一次的城市名字

Cursor cursor = citydb.select("city_table");if (cursor.moveToLast()) {cursor.moveToLast();cname = cursor.getString(cursor.getColumnIndex("city_name"));}

4.1.2.5 备忘录列表实现

从数据库读取并进行刷新显示public void RefreshNotesList() {// 如果dataList已经有的内容,全部删掉 // 并且更新simp_adapterint size = dataList.size();if (size > 0) {dataList.removeAll(dataList); simple_adapter.notifyDataSetChanged();}// 从数据库读取信息Cursor cursor=memorydb.select("memory_table");while (cursor.moveToNext()) {String name = cursor.getString(cursor.getColumnIndex("memeory_content"));String date = cursor.getString(cursor.getColumnIndex("memeory_date"));Map<String, Object> map = new HashMap<String, Object>();map.put("tv_content", name); map.put("tv_date", date); //放于TextViewdataList.add(map); }simple_adapter = new SimpleAdapter(this, dataList, R.layout.mem_item,new String[] { "tv_content", "tv_date" }, new int[] {R.id.tv_content, R.id.tv_date });listview.setAdapter(simple_adapter);}

4.1.2.6 备忘录编辑实现

通过标志位区分public int enter_state = 0;// 0是新建一个备忘录,1是修改已有备忘录SQLiteDatabase db = memorydb.getReadableDatabase();// 获取edittext内容 String content = et_content.getText().toString();// 标志为0---添加一个新的记录 if (enter_state == 0) {if (!content.equals("")) {// 获取此时时刻时间Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy MM dd");String dateString = sdf.format(date); // 向数据库添加信息ContentValues values = new ContentValues();values.put("memeory_content", content);values.put("memeory_date", dateString); db.insert("memory_table", null, values);finish();}else {Toast.makeText(noteEditActivity.this, "请输入你的内容!",Toast.LENGTH_SHORT).show();}}else {// 标志位1--查看并修改一个已有的日志ContentValues values = new ContentValues();values.put("memeory_content", content);db.update("memory_table", values, "memeory_content = ?",new String[] { last_content });finish();}

4.1.2.7 备忘录长按和短按实现不同效果

// 点击listview中某一项item的点击监听事件public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {String content = listview.getItemAtPosition(arg2) + "";String content1 = content.substring(content.indexOf("=") + 1,content.indexOf(","));//截取字符串content内容Intent myIntent = new Intent(NoteActivity.this, noteEditActivity.class);Bundle bundle = new Bundle();bundle.putString("info", content1);bundle.putInt("enter_state", 1);//状态变为修改myIntent.putExtras(bundle);startActivity(myIntent); }// 点击listview中某一项长时间的点击事件@Overridepublic boolean onItemLongClick(AdapterView<?> arg0, View arg1,final int arg2, long arg3) {Builder builder = new Builder(this);builder.setTitle("删除该备忘录");builder.setMessage("确认删除吗?");builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {String content = listview.getItemAtPosition(arg2) + "";String content1 = content.substring(content.indexOf("=") + 1,content.indexOf(","));DB.delete("memory_table", "memeory_content = ?", new String[] { content1 });RefreshNotesList();//删除后进去刷新}});builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}});builder.create();builder.show();return true; }

4.1.2.8 日历实现

我们要实现的日历控件采用ViewPager作为主框架,CalendarView继承ViewPager,这样就天生拥有左右滑动和缓存的功能。目前我们设定日历左右滑动为月份切换的操作,每一个月份显示通过自定义ViewGroup实现,也就是我们的MonthView,月份中的日期是通过layout布局解析出的View,根据月份的不同每个MonthView可能包含6 x 7或5 x 7个日期View,由于给ViewPager绑定数据需要通过PagerAdapter,所以继承PagerAdapter我们扩展了一个CalendarPagerAdapter,来完成MonthView的相关初始化和日期数据的绑定。每个MonthView的日期数据应该由上个月的后0~6天、当前月的天数和下个月的前0~6天组成。首先计算出当前月有多少天,这个简单,以及根据年月算出当前月的第一天是星期几:返回0代表周日,1~6代表周一到周六,总页数应由日历的起始年月得到,其实就是确定ViewPager的总页数MonthView继承ViewGroup,也就是日历的每一页,接收到日期数据后,在MonthView中根据数据构造对应的日期View,然后添加View到MonthView中,最后通过onMeasureonLayout确定每个View最终大小和位置。

5.1 章   软 件 测 试

5.1.1 测试目的

(1) 确认软件的质量,确保软件能正常运行,并且达到了期待中的效果

(2) 确认信息的正确性。确保从网上下载的天气情况与实际的天气情况没有什么差别

6.1 章   总 结 与 展 望

本系统基本实现了需求的中的天气预报的功能,界面设计较漂亮,具有一定的实用性。其中的天气数据全部来源于和风天气API,定位基于高德API,故在运行时一定要确保系统所处环境的网络流畅性。

由于开发基于夜神模拟器Android4.4.2 测试结果有一定局限性,可能存在由于手机分辨率不同导致页面无法显示预想的效果。

但是由于时间有限,所以在整个软件中的内容还有一些不太完善,还存在着一些尚待提高和改进的地方。希望能在以后的学习中能够不断的完善和改进。如可以将备忘录部分按时间的重要性进行分类排序,并可以增加对备忘录的属性分类等功能。

参考文献

  1. 高德定位SDK开发文档    http://lbs.amap.com/api/android-location-sdk/locationsummary/
  2. 和风API接口说明文档   https://www.heweather.com/documents/api/v5
  3. JSON解析中的手动和使用GSON解析 http://www.cnblogs.com/zhujiabin/p/5498272.html
  4. 日历实现   http://www.jianshu.com/p/304c8e70d0bd

ps.

CTRL+D收藏一下或者关注走一波-有你所需!不断更新!

其他相关下载,配套代码以及PPT。稳妥的小老弟

 https://me.csdn.net/download/qq_27500493

和风天气预报AndroidAPP-安卓(包含功能:天气预报-备忘录-高德地图定位-日历)相关推荐

  1. 安卓开发 高德地图定位的封装 十分钟上手

    前言 地图作为开发中三方sdk中较常遇到的一项,集成起来并不麻烦但是不小心踩坑可能会浪费较多时间,如果项目中多处使用还容易造成代码大量冗余,今天我们来将高德地图定位功能集成一个功能化模块,只需两分钟应 ...

  2. Android项目集成高德地图定位功能

    1.在Project的build.gradle文件中配置repositories,添加maven或jcenter仓库地址 Android Studio默认会在Project的build.gradle为 ...

  3. android 高德地图 lbstraceclient,安卓高德地图定位篇-(1)

    安卓高德地图定位.先看效果图: STEP1: 先去高德开放平台注册账号,这个不用多说吧 网址:https://lbs.amap.com/ 之后再去控制台-应用管理找到自己的key,如下图所示 STEP ...

  4. android中高德地图定位功能并且获取定位的城市

    一.概述 今天再一次用到了地图定位功能和地图显示功能,以前一直用的是高德地图定位,这次还是用高德,记录一下以便以后再做时方便一些.因为业务需要的功能不是很全,可以参考https://www.2cto. ...

  5. android wifi定位不了,h5网页使用高德地图定位正常,网页嵌入安卓app后wifi定位正常,4g网络无法定位?...

    问题描述 h5网页使用高德地图定位正常,网页嵌入安卓app后wifi定位正常,4g网络无法定位 问题出现的环境背景及自己尝试过哪些方法 h5网页手机浏览器打开没有问题,嵌入app后打包,安卓9.0系统 ...

  6. flutter 获取定位_10分钟让你的flutter程序拥有定位功能--集成高德地图定位指南...

    地图定位这个功能目前基本上是商业应用app的标配.然而,在flutter中进行原生功能的开发,意味着必须的ios和android双端都通,而且需要大量的调试时间.尤其目前这个时间点,flutter的版 ...

  7. 安卓系统的导航仪怎么设置导航启动路径为高德地图_界面功能焕然一新!高德地图10.0新版体验...

    [PConline应用]近日高德地图10.0安卓版与iOS版同时上线,作为一名资深高德迷,我自然第一时间下载并更新了它.没让我失望的是,此次新版不但用上了全新的扁平式UI,各项功能模块也有了大幅进步, ...

  8. 安卓使用javascriptApi快速开发高德地图

    由于目前某些安卓app的开发并不需要对地图的开发很深入,所以高德地图也推出了地图快速开发组件,个人觉得其实还是蛮好的,能够很好的实现app的某些功能,如果你的app并不需要地图的覆盖物这些功能的话,那 ...

  9. 安卓系统高德怎么定位服务器,怎么使用高德地图定位和导航功能?

    去到一个陌生的城市,我们往往会因为无法明辨位置方向感到茫然无措,这个时候地图就发挥了它的作用.现在我们常常会在手机里安装地图软件,可以通过手机软件导航来定位和寻找目的地.今天,小编就来说说怎么用高德地 ...

最新文章

  1. IDEA控制台输出乱码解决方案
  2. 深入理解分布式技术 - 读写分离场景及注意事项解读
  3. 25 类:接口 抽象父类 多态 鸭子类型 格式化方法与析构方法 反射 异常处理 自定义异常 断言...
  4. 两台centos之间传送文件
  5. 【深度学习】短袖短裤识别算法冠军方案总结
  6. 第六天,字典Dictionary
  7. 转载:tensorflow保存训练后的模型
  8. Maven3.0.5代理nexus
  9. 杨振宁在物理学界的地位和成就
  10. 基因行业容器存储解决方案
  11. mongodb mysql资源占用_如何限制mongodb启动时占用过多内存
  12. 解决数据库密码为YES的问题
  13. 使用Eclipse查看反编译后的代码(Decompiler 插件)
  14. java中bean的作用域有哪些_深入了解Spring中Bean的作用域和生命周期
  15. 同是4G标准,TD和FDD谁更快?
  16. 最好用的屏幕录像软件,三步实现高清录制?
  17. VPS部署以及域名设置和DNS解析
  18. [笔记] Codeforces#274 Riding in a Lift (479E) DP
  19. 我的linux系统怎么输入pv,如何在Linux系统中使用pv命令
  20. 【转】预装Win8/8.1 中文版系统升级为专业版或专业版含媒体中心版的简单方法...

热门文章

  1. RFID电子标签有哪些区
  2. 笔记............................
  3. [Rotation Transform] 旋转变换
  4. 如何利用python准确预测双色球开奖结果
  5. oa系统服务器什么意思,OA系统是什么意思
  6. uni-app中设置不同平台显示不同的样式
  7. 电脑wifi已连接,登录QQ客户端有网,但打开网页没有网?
  8. Teigha的BlockTableRecord获取方法
  9. 怪物猎人世界取得服务器信息,怪物猎人世界 Steam好友联机服务器选择工具V1.2...
  10. fpga/嵌入式硬件初级工程师必备链接(不定时更新)