Android - 实训项目总结
16lz
2021-01-23
Android1.简介1.1项目简介 Coolweather是一款基于Android的天气查询软件,实现了省市县的遍历、县级地区天气的查询、手动更新天气、8小时的自动更新天气信息;1.2项目责任 xx:测试代码的编写实现 xx:软件调式修改 xx:项目框架和文档编写1.3项目内容 项目结构:-com.example.app--activity---ChooseAreaActivity---WeatherActivity--db---CoolWeatherOpenHelper---CoolWeatherDB--model---Province---City---County--receiver---AutoUpdateReceiver--service---AutoUpdateService--util---HttpUtil---HttpCallbackListenerPS:activity 包用于存放所有活动相关的代码,---ChooseAreaActivity 遍历省市县数据---WeatherActivity 显示天气活动db 包用于存放所有数据库相关的代码,---CoolWeatherOpenHelper 数据库辅助类,创建一个数据库+三张表---CoolWeatherDB 数据库数据操作封装类model 包用于存放所有模型相关的代码,---Province 省实体类---City 市实体类---County 县实体类receiver 包用于存放所有广播接收器相关的代码,---AutoUpdateReceiver 自动更新天气service 包用于存放所有服务相关的代码,---AutoUpdateService 手动更新天气util 包用于存放所有工具相关的代码---HttpUtil---HttpCallbackListener 与服务器的交互类2.核心代码// db->CoolWeatherDB->saveCity(...)// 将City实例存储到数据库public void saveCity(City city) { if (city != null) { ContentValues values = new ContentValues(); values.put("city_name", city.getCityName()); values.put("city_code", city.getCityCode()); values.put("province_id", city.getProvinceId()); db.insert("City", null, values); }}// db->CoolWeatherDB->loadCities(...)// 读取某省内所有城市数据public List loadCities(int provinceId) { List list = new ArrayList(); Cursor cursor = db.query("City", null, "province_id = ?",new String[] { String.valueOf(provinceId) }, null, null, null); if (cursor.moveToFirst()) { do { City city = new City(); city.setId(cursor.getInt(cursor.getColumnIndex("id"))); city.setCityName(cursor.getString(cursor.getColumnIndex("city_name"))); city.setCityCode(cursor.getString(cursor.getColumnIndex("city_code"))); city.setProvinceId(provinceId); list.add(city); } while (cursor.moveToNext()); } return list;}// util->HttpUtil->sendHttpRequest(...)// 发送HTTP请求到服务器,获取返回的结果public static void sendHttpRequest(final String address,final HttpCallbackListener listener) { new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; try { URL url = new URL(address); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } if (listener != null) { // 回调onFinish()方法 listener.onFinish(response.toString()); } } catch (Exception e) { if (listener != null) { // 回调onError()方法 listener.onError(e); } } finally { if (connection != null) { connection.disconnect(); } } } }).start(); }// util->HttpUtil->handleCitiesResponse(...)// 解析http请求返回的数据(省市县)public static boolean handleCitiesResponse(CoolWeatherDB coolWeatherDB,String response, int provinceId) { if (!TextUtils.isEmpty(response)) { //按逗号分隔 String[] allCities = response.split(","); if (allCities != null && allCities.length > 0) { for (String c : allCities) { //按单竖线分隔 String[] array = c.split("\\|"); City city = new City(); city.setCityCode(array[0]); city.setCityName(array[1]); city.setProvinceId(provinceId); // 将解析出来的数据存储到City表 coolWeatherDB.saveCity(city); } return true; } } return false; }// util->HttpUtil->handleWeatherResponse(...)// 解析http请求返回的天气数据public static void handleWeatherResponse(Context context, String response) { try { String temp = new String(response.getBytes(), "utf-8");// 将数据以utf-8的编码方式获取出来 JSONObject dataOfJson = new JSONObject(temp); JSONArray heWeatherArray = dataOfJson.getJSONArray("HeWeather data service 3.0"); JSONObject heWeatherArray0 = heWeatherArray.getJSONObject(0); JSONObject basic = heWeatherArray0.getJSONObject("basic"); String cityName = basic.getString("city"); String weatherCode0 = basic.getString("id"); String weatherCode = weatherCode0.substring(2, 11); JSONObject updateJson = basic.getJSONObject("update"); String publishTime0 = updateJson.getString("loc"); String publishTime = publishTime0.substring(11, 16); JSONArray daily_forecast = heWeatherArray0.getJSONArray("daily_forecast"); JSONObject daily_forecast0 = daily_forecast.getJSONObject(0); JSONObject cond = daily_forecast0.getJSONObject("cond"); String txt_d = cond.getString("txt_d"); String txt_n = cond.getString("txt_n"); String weatherDiscribe; if (txt_d.equals(txt_n)) { weatherDiscribe = txt_d; } else { weatherDiscribe = txt_d + "转" + txt_n; } JSONObject tmp = daily_forecast0.getJSONObject("tmp"); String temp10 = tmp.getString("min"); String temp1 = temp10 + "℃"; String temp20 = tmp.getString("max"); String temp2 = temp20 + "℃"; Log.d("Utility", cityName + weatherCode + temp1 + temp2+ weatherDiscribe + publishTime); saveWeatherInfo(context, cityName, weatherCode, temp1, temp2,weatherDiscribe, publishTime); } catch (JSONException e) { e.printStackTrace(); } }// activity->ChooseAreaActivity->queryCities()// 查询选中市内所有的县,优先从数据库查询,如果没有查询到再去服务器上查询 private void queryCities() { cityList = coolWeatherDB.loadCities(selectedProvince.getId()); if (cityList.size() > 0) { dataList.clear(); for (City city : cityList) { dataList.add(city.getCityName()); } adapter.notifyDataSetChanged(); listView.setSelection(0); titleText.setText(selectedProvince.getProvinceName()); currentLevel = LEVEL_CITY; } else { queryFromServer(selectedProvince.getProvinceCode(), "city"); } }// activity->ChooseAreaActivity->queryFromServer(...)// 去服务器上查询private void queryFromServer(final String code, final String type) { String address; if (!TextUtils.isEmpty(code)) { address = "http://www.weather.com.cn/data/list3/city" + code +".xml"; } else { address = "http://www.weather.com.cn/data/list3/city.xml"; } showProgressDialog(); HttpUtil.sendHttpRequest(address, new HttpCallbackListener() { @Override public void onFinish(String response) { boolean result = false; if ("province".equals(type)) { result = Utility.handleProvincesResponse(coolWeatherDB,response); } else if ("city".equals(type)) { result = Utility.handleCitiesResponse(coolWeatherDB,response, selectedProvince.getId()); } else if ("county".equals(type)) { result = Utility.handleCountiesResponse(coolWeatherDB,response, selectedCity.getId()); } if (result) { // 通过runOnUiThread()方法回到主线程处理逻辑 runOnUiThread(new Runnable() { @Override public void run() { closeProgressDialog(); if ("province".equals(type)) { queryProvinces(); } else if ("city".equals(type)) { queryCities(); } else if ("county".equals(type)) { queryCounties(); } } }); } } @Override public void onError(Exception e) { // 通过runOnUiThread()方法回到主线程处理逻辑 runOnUiThread(new Runnable() { @Override public void run() { closeProgressDialog(); Toast.makeText(ChooseAreaActivity.this,"加载失败", Toast.LENGTH_SHORT).show(); } }); } }); }// activity->WeatherActivity>queryWeatherInfo(...)// 根据天气代号查询天气信息private void queryWeatherInfo(String weatherCode) { String address = "http://api.heweather.com/x3/weather?cityid=CN"+ weatherCode + "&key=3e9f4017110547f2b74237fdc7152f38"; queryFromServer(address, "weatherCode");}// Service->AutoUpdateService>onStartCommand(...)// 更新天气public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { updateWeather(); } }).start(); AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); int anHour = 8 * 60 * 60 * 1000; // 这是8小时的毫秒数 long triggerAtTime = SystemClock.elapsedRealtime() + anHour; Intent i = new Intent(this, AutoUpdateReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); return super.onStartCommand(intent, flags, startId);}// Service->AutoUpdateService>updateWeather(...)// 更新天气SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);String weatherCode = prefs.getString("weather_code", "");String address = "http://api.heweather.com/x3/weather?cityid=CN"+ weatherCode + "&key=3e9f4017110547f2b74237fdc7152f38";HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {........}// Receiver>AutoUpdateReceiver// 自动更新天气public class AutoUpdateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(context, AutoUpdateService.class); context.startService(i); }}//定时处理AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);int anHour = 8 * 60 * 60 * 1000; // 这是8小时的毫秒数long triggerAtTime = SystemClock.elapsedRealtime() + anHour;Intent i = new Intent(this, AutoUpdateReceiver.class);PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);return super.onStartCommand(intent, flags, startId);3.项目总结 实习期间,做了一个Android小项目;虽然已经学了很久,但是真到自己动手的时候会发现遇到了各种问题; 首先,讲述一下从中获得了什么? (1)CoolWeather这款软件主要利用了HttpURLConnection完成HTTP请求,进行对返回数据的XML解析、JSON解析; (2)运用了数据库SQLiteDateBase进行省市县数据的存储以及操作, (3)运用SharedPreferences,进行实时天气信息的存储 (4)Service 服务的后台运行 (5)Receiver 广播接收器的定时处理 其次,简单讲述一下遇到的问题 (1)广播接收器运用时,onReceive()总是崩溃 - 忘记注册(已解决) (2)UI界面更新会出现ANR错误 - 延时处理的操作没有在子线程完成(已解决) (3)ListView数据没有实时显示 - 适配器未提醒更新(已解决) 最后,感谢这样的一次实习机会,Android开发水平有了进一步的提升;
更多相关文章
- Android:android.git.kernel.org 无法访问时下载源代码的解决方法
- Android 数据存取
- [Tools]Android Studio代码提示功能--Ctrl+Alt+Space(空格键)
- Android 之 使用File类在SD卡中读取数据文件
- Android学习心得(14) --- Android代码混淆(2)
- 一网打尽__Android 开源代码合集(SwitchButton)
- DSBridge——一套H5代码就能同时与Android和iOS通信