主要功能
- 省市县三级列表展示城市,按选择查询对应城市的当天天气和近期天气情况
- 可以手动的切换城市
- 可以手动更新天气以及后台的自动更新天气
- 自定义折线图显示近期的温度变化
桌面小组件实时显现天气和时间
效果图如下
这个小应用开发过程中用到的自定义View–折线图和实践–桌面小组件之天气小组件在前面的博客中都有讲解,如有疑惑,请前往查看。
数据的获取
http://www.weather.com.cn/data/list3/city.xml
- 这个网址返回的是全国所有的省的数据,大家访问自行查看数据内容,里面包含了省名称和省id,id就用于继续查询市级信息
address = "http://www.weather.com.cn/data/list3/city"+id+".xml";
- 上面的id就用来继续拼接成上述网址,用来查询对应的省下属的市级列表,返回的数据一样,是市名称和市id
同样的查询县级信息和上面一样,不过将id换为市id,用来查询下属的县级信息。
获取到县的信息和id,在次发送消息,我们就能获取到对应县的天气的id了,通过天气的id我们就能获取相应的县的天气了
http://api.k780.com:88/?app=weather.future&weaid=" + substring + "&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=xml
我们将substring对应换成就可以获取到相应的县的近7天的天气信息了,返回的数据是xml格式的数据 ,我们对应解析就可以了。
例如江苏省 id为19
- 苏州 id为1904
- 昆山 id为190404
- 昆山对应的天气id为101190404
- 下面为对应的代码
/**
* 根据传入的代号和类型从服务器上查询省市县数据。
*/
private void queryFromServer(final String code, final String type, final int position) {
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";
}
if (!dialog.isShowing()) {
dialog.show();
}
HttpUtils.sendHttpRequest(address, new HttpUtils.HttpCallbackListener() {
@Override
public void onFinish(String response) {
boolean result = false;
if ("province".equals(type)) {
result = HandleResponceUtils.handleProvincesResponse(coolWeatherDB,
response);
} else if ("city".equals(type)) {
result = HandleResponceUtils.handleCitiesResponse(coolWeatherDB,
response, provinceList.get(position).getId());
} else if ("county".equals(type)) {
result = HandleResponceUtils.handleCountiesResponse(coolWeatherDB,
response, cityList.get(position).getId());
}
if (result) {
// 通过runOnUiThread()方法回到主线程处理逻辑
runOnUiThread(new Runnable() {
@Override
public void run() {
if (dialog.isShowing()) {
dialog.dismiss();
}
if ("province".equals(type)) {
queryProvinces();
} else if ("city".equals(type)) {
queryCities(position);
} else if ("county".equals(type)) {
queryCounties(position);
}
}
});
}
}
@Override
public void onError(Exception e) {
// 通过runOnUiThread()方法回到主线程处理逻辑
runOnUiThread(new Runnable() {
@Override
public void run() {
if (dialog.isShowing()) {
dialog.dismiss();
}
Toast.makeText(ChooseAreaActivity.this, "请检查手机网络", Toast.LENGTH_SHORT).show();
}
});
}
});
}
- 对应的网络处理的类就是
public class HttpUtils {
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
}
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();
}
}
#
数据库的设计
首先我们根据上面的数据信息,需要建三张表
省名称和对应的省id的表
市名称和对应的市id,以及市所属的省的id的表
县名称和对应县的天气的id,以及县所属的市的id的表
同时还有一个我们用于保存目前定位的城市的天气信息的表
界面展示
- 界面展示我们选择用Viewpager来展示两个Fragment,分别展示当天天气和一周天气的情况
- 具体布局如下
- 当天天气
- 近期天气
近期天气使用了n个竖直的线性布局,线性布局中在放置对应的天气信息的控件
下方放置一个天气的折线图控件
后台的更新
我们检测开机的广播,实现开机我们就开启后台的服务,在服务中设置定时逻辑,当时间到了之后,我们就执行更新天气的代码逻辑。
同时我们在每次开启软件的时候,也进行服务的开启逻辑,如果服务微开启,那么我们开启软件的同时,服务也会启动
//定时两小时更新数据库天气信息
AlarmManager manager= (AlarmManager) getSystemService(ALARM_SERVICE);
int alarmTime=60*2*60*1000;
long time= System.currentTimeMillis()+alarmTime;
PendingIntent i=PendingIntent.getBroadcast(this,0,new Intent("START_AlARM"),0);
manager.set(AlarmManager.RTC_WAKEUP,time,i);
整体逻辑
我们每次进入程序都先查询数据库中的天气的表中是否有数据,若有,我们就直接进入天气展示界面,将获取的天气信息展示在界面上,如果为获取相应的天气信息,我们就进入城市选择界面,选择城市的时候我们是先从数据库查询城市信息,没有的话,再去服务器查询城市信息并先保存到本地数据库以便下次查询使用。当我们点击相应的城市列表的名称,我们就去服务器获取新的天气信息,同时删除本地天气信息,将新获取的天气信息保存即可。
整体的逻辑就是这样的,再有就是一些小细节的知识,比如UI的及时更新,桌面小组件的实时显示,直接根据天气图片的网址,将图片显示在界面上等等。
-
如果对上面的讲解疑惑,如果有需要,欢迎下载天气APP源码
在源码中,大部分方法、代码我都加了相应的功能逻辑的注释,这样可以保证你阅读源码更易于理解*
数据的提供地址:
网址,最后的cityKey就是对应的城市id(一周的天气)
http://api.k780.com:88/?app=weather.future&weaid=101010100&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=xml
- 这是另外一个可用的获取城市名称和id的网址
查询城市名称和id的网址,返回的是xml数据,可以使用xml数据解析,获取的是全国所有的县的信息
http://api.k780.com:88/?app=weather.city&format=xml