主要功能
- 省市縣三級列表展示城市,按選擇查詢對應城市的當天天氣和近期天氣情況
- 可以手動的切換城市
- 可以手動更新天氣以及後臺的自動更新天氣
- 自定義折線圖顯示近期的溫度變化
桌面小組件實時顯現天氣和時間
效果圖如下
這個小應用開發過程中用到的自定義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