Android
1.简介
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
---HttpCallbackListener
PS:
activity 包用于存放所有活动相关的代码,
---ChooseAreaActivity 遍历省市县数据
---WeatherActivity 显示天气活动
db 包用于存放所有数据库相关的代码,
---CoolWeatherOpenHelper 数据库辅助类,创建一个数据库+三张表
---CoolWeatherDB 数据库数据操作封装类
model 包用于存放所有模型相关的代码,
---Province 省实体类
---City 市实体类
---County 县实体类
receiver 包用于存放所有广播接收器相关的代码,
---AutoUpdateReceiver 自动更新天气
service 包用于存放所有服务相关的代码,
---AutoUpdateService 手动更新天气
util 包用于存放所有工具相关的代码
---HttpUtil
---HttpCallbackListener 与服务器的交互类
2.核心代码
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);
}
}
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;
}
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) {
listener.onFinish(response.toString());
}
} catch (Exception e) {
if (listener != null) {
listener.onError(e);
}
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
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);
coolWeatherDB.saveCity(city);
}
return true;
}
}
return false;
}
public static void handleWeatherResponse(Context context, String response) {
try {
String temp = new String(response.getBytes(), "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();
}
}
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");
}
}
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(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(new Runnable() {
@Override
public void run() {
closeProgressDialog();
Toast.makeText(ChooseAreaActivity.this,"加载失败", Toast.LENGTH_SHORT).show();
}
});
}
});
}
private void queryWeatherInfo(String weatherCode) {
String address = "http://api.heweather.com/x3/weather?cityid=CN"+ weatherCode + "&key=3e9f4017110547f2b74237fdc7152f38";
queryFromServer(address, "weatherCode");
}
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;
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);
}
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() {........}
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;
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开发水平有了进一步的提升;