(原创)悟空天气------Android源码下载地址,代码结构与解析,附App截图
来源:互联网 发布:马克斯 cms 教程 编辑:程序博客网 时间:2024/04/29 15:59
前言
几个月前前就想把自己做的这款天气类的App写在自己的博客上,由于各种原因(主要是懒)一直耽误下去,前段时间对自己的代码进行更新,版本更新到version2.0觉得不能再拖了,就诞生了这篇博文,希望各位看官碰到本文错误的地方,可以及时与我沟通。
悟空天气简介
源码下载链接:悟空天气GitHub下载地址
version1.0版本源码下载链接:version1.0版本源码下载地址
version2.0版本
悟空天气采用权威数据源授权信息,拥有众多城市的天气预报和实时天气预警信息;更可查看大城市的空气质量情况。
特色功能:
1.简约
2.精确预报6天天气
3.查询空气质量
4.采用Matrial Design风格的侧滑菜单,以及support v7包的控件
5.使用数据库存储城市列表信息,采用内存缓存及文件缓存两种方式存储天气信息。
6.使用自定义view,创建圆形pm2.5的自定义view显示空气状况。
软件截图:
代码结构解析
- adapter—存放菜单城市列表,城市数据库,Fragment的包。
重点内容 2. App—存放自定义Appliation。 - bean—存放Item,如City,Pm2.5信息,简单天气状况,详细天气状况,及天气预报。
- db—-使用SQLiteOpenHelper及SQLiteDatabase类的包。
- Fragment—各种用到的Fragment。
- fragmentViewPager—-滑动式5天天气预报,较好的操作效果。
- indicator—-fragment工具类。
- support—–工具类
- ui—-下拉刷新包
- util—-工具类
- weather—–主activity包。
代码主要部分
1.Application类
初始化操作类,如下:
private void initData() { mApplication = this; mNetWorkState = NetUtil.getNetworkState(this); initCityList(); mLocationClient = new LocationClient(this, getLocationClientOption()); initWeatherIconMap(); initWidgetWeather(); mSpUtil = new SharePreferenceUtil(this, SharePreferenceUtil.CITY_SHAREPRE_FILE); IntentFilter filter = new IntentFilter(NET_CHANGE_ACTION); registerReceiver(netChangeReceiver, filter); }
获取网络状态,初始化城市列表,获取定位信息,初始化天气图标及widget。
2.MainActivity类
这个是核心类,内容包括:加入侧滑菜单,开启线程获取天气状况及pm值,更新天气模块(包括无网络或无响应时如何更新),获取定位位置,更新ui操作,防止滑动冲突。
下面是添加侧滑菜单的代码,这里是使用了 mikepenz/MaterialDrawer的具有material风格的侧滑菜单,链接介绍地址。
header = new AccountHeaderBuilder().withActivity(this) .withCompactStyle(false) .withHeaderBackground(R.drawable.main_nav_header_bg) .addProfiles(new ProfileDrawerItem().withIcon(R.drawable.ic_launcher).withEmail(getString(R.string.author_email)).withName(getString(R.string.author_name))) .build(); // set creator drawer = new DrawerBuilder().withActivity(this) .withAccountHeader(header) .addDrawerItems(new PrimaryDrawerItem().withName("添加城市").withIcon(R.drawable.behind_add_city).withIdentifier(R.drawable.behind_add_city) ) .build(); drawer.setOnDrawerItemClickListener(this); addAllMenuItem(databaseHelper.getReadableDatabase()); drawer.addStickyFooterItem(new SectionDrawerItem().withName("悟空天气")); drawer.addStickyFooterItem(new SectionDrawerItem().withName("设置")); drawer.addStickyFooterItem(new SectionDrawerItem().withName("关于"));
本应用主要通过4个Message值来更新ui:
private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case LOACTION_OK: String cityName = (String) msg.obj; L.i("cityName = " + cityName); mCurCity = mCityDB.getCity(cityName); L.i(mCurCity.toString()); mSpUtil.setCity(mCurCity.getCity()); cityTv.setText(mCurCity.getCity()); frame.postDelayed(new Runnable() { @Override public void run() { frame.autoRefresh(true); } }, 100); break; case ON_NEW_INTENT: mCurCity = mNewIntentCity; mSpUtil.setCity(mCurCity.getCity()); cityTv.setText(mCurCity.getCity()); frame.autoRefresh(); updateWeather(true); break; case UPDATE_EXISTS_CITY: String sPCityName = mSpUtil.getCity(); mCurCity = mCityDB.getCity(sPCityName); updateWeather(false); break; case GET_WEATHER_RESULT: updateWeatherInfo(); updatePm2d5Info(); updateWidgetWeather(); break;
LOACTION_OK:在刚开始使用Gps定位时,获取定位成功将传LOACTION_OK值进行第一次获取天气操作。
ON_NEW_INTENT:点击添加城市来新增城市天气时,所返回的值操作。
UPDATE_EXISTS_CITY:刷新已有城市返回的值。
GET_WEATHER_RESULT:返回天气信息时所返回的值。
下面代码为获取天气的核心代码:
private void updateWeather(final boolean isRefresh) { if (NetUtil.getNetworkState(getContext()) == NetUtil.NETWORN_NONE && isRefresh) { T.showLong(getActivity(), R.string.net_err); return; } if (mCurCity == null) { T.showLong(mApplication, "未找到此城市,请重新定位或选择..."); return; } // T.showShort(this, "正在刷新天气..."); timeTv.setText("同步中..."); // 启动线程获取天气信息 new Thread() { @Override public void run() { super.run(); getWeatherInfo(isRefresh); getPm2d5Info(isRefresh); if (mCurWeatherinfo != null) L.i(mCurWeatherinfo.toString()); if (mCurPm2d5 != null) L.i(mCurPm2d5.toString()); mHandler.sendEmptyMessage(GET_WEATHER_RESULT); } }.start(); }
下面 为解析天气的方法:
private void parseWeatherInfo(String url, String result, boolean isRefreshWeather) { mCurWeatherinfo = null; mCurWeatherinfo = mApplication.getmCurWeatherinfo(); mApplication.setmCurWeatherinfo(null); if (!TextUtils.isEmpty(result) && !result.contains("页面没有找到")) { // L.i(result); try { mCurWeatherinfo = JsonForWeather.getCurrentWeather(result); mPreWeatherinfo = JsonForWeather.getForecastWeather(result); ((MainActivity) getActivity()).setFragment_weatherinfo(mCurWeatherinfo); } catch (JSONException e) { e.printStackTrace(); } } else { } ConfigCache.setUrlCache(result, url); }
同样解析pm的值的方法:
private void parsePm2d5Info(String url, String result, boolean isRefreshPm2d5) { mCurPm2d5 = null; System.out.println("---------" + result); mApplication.setmCurWeatherinfo(null); if (!TextUtils.isEmpty(result)) { // L.i(result); try { mCurPm2d5 = JSonForPm.getPm2d5Object(result); ((MainActivity) getActivity()).setFragment_pm(mCurPm2d5); System.out.println("++++++++" + mCurPm2d5); } catch (JSONException e) { e.printStackTrace(); } // L.i(mCurPm2d5.toString()); } else { result = ""; } if (isRefreshPm2d5 && !TextUtils.isEmpty(result)) // save2File(result, PM2D5_INFO_FILENAME); ConfigCache.setUrlCache(result, url); }
获取天气方法:
private void getPm2d5Info(boolean isRefresh) { String urlPm2d5 = PM2D5_BASE_URL.replace("商丘", mCurCity.getCity()); String result; if (!isRefresh) { if (mApplication.getmCurPm2d5() != null) {// 内存中的信息 mCurPm2d5 = mApplication.getmCurPm2d5(); ((MainActivity) getActivity()).setFragment_pm(mCurPm2d5); L.i("get the pm2.5 info from memory"); return; } result = ConfigCache.getUrlCache(urlPm2d5); if (!TextUtils.isEmpty(result)) { parsePm2d5Info(urlPm2d5, result, false); L.i("get the pm2.5 info from file"); return; } } // L.i("pm2.5 url: " + urlPm2d5); String pmResult = connServerForResult(urlPm2d5); if (TextUtils.isEmpty(pmResult) || pmResult.contains("reason")) {// 如果获取失败,则取本地文件中的信息, String fileResult = getInfoFromFile(PM2D5_INFO_FILENAME); // 只有当本地文件信息与当前城市相匹配时才使用 if (!TextUtils.isEmpty(fileResult) && fileResult.contains(mCurCity.getCity())) pmResult = fileResult; } // pmResult = getInfoFromFile(PM2D5_INFO_FILENAME); parsePm2d5Info(urlPm2d5, pmResult, true); }
更新界面操作:
private void updatePm2d5Info() { if (mCurPm2d5 != null) { mApplication.setmCurPm2d5(mCurPm2d5); pmQualityTv.setText(mCurPm2d5.getQuality()); pmDataTv.setText(mCurPm2d5.getPm()); int pm2_5 = Integer.parseInt(mCurPm2d5.getPm()); int pm_img = R.drawable.biz_plugin_weather_0_50; if (pm2_5 > 300) { pm_img = R.drawable.biz_plugin_weather_greater_300; } else if (pm2_5 > 200) { pm_img = R.drawable.biz_plugin_weather_201_300; } else if (pm2_5 > 150) { pm_img = R.drawable.biz_plugin_weather_151_200; } else if (pm2_5 > 100) { pm_img = R.drawable.biz_plugin_weather_101_150; } else if (pm2_5 > 50) { pm_img = R.drawable.biz_plugin_weather_51_100; } else { pm_img = R.drawable.biz_plugin_weather_0_50; } pmImg.setImageResource(pm_img); } else { pmQualityTv.setText("N/A"); pmDataTv.setText("N/A"); pmImg.setImageResource(R.drawable.biz_plugin_weather_0_50); T.showLong(mApplication, "未获取到PM2.5数据"); } }
网络操作:
public static String request(String httpUrl) { BufferedReader reader = null; String result = null; StringBuffer sbf = new StringBuffer(); try { URL url = new URL(httpUrl); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.connect(); InputStream is = connection.getInputStream(); reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); String strRead = null; while ((strRead = reader.readLine()) != null) { sbf.append(strRead); sbf.append("\r\n"); } reader.close(); result = sbf.toString(); } catch (Exception e) { e.printStackTrace(); } return result; }
还有一些详细介绍,后续再继续更新。
后言
本文还有对代码其余部分未作介绍,后面时间会陆续写出来,这款App也会一直更新,
我的GitHub地址
我的博客地址
- (原创)悟空天气------Android源码下载地址,代码结构与解析,附App截图
- Android项目:Cool Weather酷欧天气(附源码)
- Android之高仿雅虎天气(二)---代码结构解析
- Android之高仿雅虎天气(二)---代码结构解析
- Android之高仿雅虎天气(二)---代码结构解析
- 下载Android 5.0源码(附源码)
- java浏览器文件下载实例(附源码下载地址)
- 几款不错的Android开源APP效果展示(附源码地址)
- Android 网络下载 google天气图标下载实例(源码)
- Android客户端与服务端(jsp)之间json的传输与解析【附效果图附源码】
- 《代码大全 》pdf下载(内附下载地址)
- 智能语音输入查询天气app附源码
- RocketMQ源码解析(1)--代码结构与模块说明
- android 截图功能源码解析
- 原创:微信小程序源码解说:石头剪刀布(附源码下载)
- android源码下载地址
- Android 源码下载地址
- Android 源码下载地址
- Oracle 中左右填充问题
- 新世界的大门正在向我打开!!!
- python进制转换(读取纯二进制文件内容)
- C++学习之模板篇(类模板)
- Maven实战 4 -- Maven核心概念
- (原创)悟空天气------Android源码下载地址,代码结构与解析,附App截图
- 这是蓝桥杯练习系统历届试题中矩阵翻硬币的答案(不过这只是一般思路下求解出的答案,仅得了10分)
- mysql操作函数列表
- String 和StringBuffer 在传递过程中的区别
- Maven实战 5 -- Maven与Eclipse整合
- 【代码笔记】iOS-翻页效果的实现
- session_save_path.php AccessSESSION.php
- 修改linux服务器时区
- js函数总结