為了讓天氣軟件更加只能,我們可以加入后台自動更新天氣的功能,這樣就可以盡可能保證用戶每次打開軟件時看到的都是最新的天氣信息。
想要實現上訴功能,就需要創建一個長期在后台運行的定時任務。首先在service包下新建一個服務,右擊com.coolweather.android.service-New-Service-Service,創建一個AutoUpdateService,並將Exported和Enabled這兩個屬性都勾中。然后修改AutoUpdateService中的代碼,如下所示:
1 public class AutoUpdateService extends Service { 2 3 @Override 4 public IBinder onBind(Intent intent) { 5 return null; 6 } 7 8 @Override 9 public int onStartCommand(Intent intent, int flags, int startId) { 10 updateWeather(); 11 updateBingPic(); 12 AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); 13 int anHour = 8 * 60 * 60 * 1000; // 這是8小時的毫秒數 14 long triggerAtTime = SystemClock.elapsedRealtime() + anHour; 15 Intent i = new Intent(this, AutoUpdateService.class); 16 PendingIntent pi = PendingIntent.getService(this, 0, i, 0); 17 manager.cancel(pi); 18 manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); 19 return super.onStartCommand(intent, flags, startId); 20 } 21 22 /** 23 * 更新天氣信息。 24 */ 25 private void updateWeather(){ 26 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 27 String weatherString = prefs.getString("weather", null); 28 if (weatherString != null) { 29 // 有緩存時直接解析天氣數據 30 Weather weather = Utility.handleWeatherResponse(weatherString); 31 String weatherId = weather.basic.weatherId; 32 String weatherUrl = "http://guolin.tech/api/weather?cityid=" + weatherId + "&key=bc0418b57b2d4918819d3974ac1285d9"; 33 HttpUtil.sendOkHttpRequest(weatherUrl, new Callback() { 34 @Override 35 public void onResponse(Call call, Response response) throws IOException { 36 String responseText = response.body().string(); 37 Weather weather = Utility.handleWeatherResponse(responseText); 38 if (weather != null && "ok".equals(weather.status)) { 39 SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(AutoUpdateService.this).edit(); 40 editor.putString("weather", responseText); 41 editor.apply(); 42 } 43 } 44 45 @Override 46 public void onFailure(Call call, IOException e) { 47 e.printStackTrace(); 48 } 49 }); 50 } 51 } 52 53 /** 54 * 更新必應每日一圖 55 */ 56 private void updateBingPic() { 57 String requestBingPic = "http://guolin.tech/api/bing_pic"; 58 HttpUtil.sendOkHttpRequest(requestBingPic, new Callback() { 59 @Override 60 public void onResponse(Call call, Response response) throws IOException { 61 String bingPic = response.body().string(); 62 SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(AutoUpdateService.this).edit(); 63 editor.putString("bing_pic", bingPic); 64 editor.apply(); 65 } 66 67 @Override 68 public void onFailure(Call call, IOException e) { 69 e.printStackTrace(); 70 } 71 }); 72 } 73 74 }
可以看到,在onStartCommand()方法中先是調用了updateWeather()方法來更新天氣,然后調用了updateBingPic()方法來更新背景圖片。這里我們將更新后的數據直接存儲到SharedPreferences文件中就可以了,因為打開WeatherActivity的時候都會優先從SharedPreferences緩存中讀取數據。
之后就是創建定時任務的技巧了,為了保證軟件不會消耗太多的流量,這里將時間間隔設置為8小時,8小時后AutoUpdateReceiver的onStartCommand()方法就會重新執行,這樣也就實現后台定時更新的功能了。
我們還需要在代碼某處去激活AutoUpdateService這個服務才行。修改WeatherActivity中的代碼,如下所示:
1 public class WeatherActivity extends AppCompatActivity{ 2 ... 3 /** 4 * 處理並展示Weather實體類中的數據 5 */ 6 private void showWeatherInfo(Weather weather){ 7 if(weather != null&& "ok".equals(weather.status)){ 8 ... 9 Intent intent = new Intent(this,AutoUpdateService.class); 10 startService(intent); 11 }else{ 12 Toast.makeText(WeatherActivity.this,"獲取天氣信息失敗",Toast.LENGTH_SHORT).show(); 13 } 14 } 15 }
這里可以看到,在showWeather()方法的最后加入啟動AutoUpdateService這個服務的代碼,這樣只要一旦選中了某個城市並成功更新天氣之后,AutoUpdateService就會一直在后台運行,並保證每8小時跟新一次天氣。
截至此,天氣軟件的主體功能都已經實現了。但我們還可以為它做更多的完善,比如修改圖標和名稱,或增加設置選項,讓用戶選擇是否允許后台自動更新天氣,以及設定更新的頻率等等。
通過這個軟件的開發,本人熟悉了UI、網絡、數據存儲、服務等技術並且加強了綜合應用的能力。
具體實現步驟連接:
android開發學習之路——天氣預報之技術分析與數據庫(一)
android開發學習之路——天氣預報之遍歷省市縣數據(二)
