后台自动更新天气
这里我们准备加入后台自动更新天气的功能,这样就可以尽可能地保证用户每次打开软件时看到的都是最新的天气信息
要想实现上述功能,就需要创建一个长期在后台运行的定时任务
首先在service包下新建一个AutoUpdateService继承自Service
public class AutoUpdateService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
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小时的毫秒数
/**
* SystemClock.elapsedRealtime()方法可以获取到系统开机至今所经历时间的毫秒数
*/
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
Intent i = new Intent(this, AutoUpdateReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
// ELAPSED_REALTIME_WAKEUP表示让定时任务的触发时间从系统开机算起,且会唤醒CPU
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
return super.onStartCommand(intent, flags, startId);
}
/**
* 更新天气信息
*/
private void updateWeather() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String weatherCode = prefs.getString("weather_code", "");
String address = "http://www.weather.com.cn/data/cityinfo/" + weatherCode + ".html";
HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {
@Override
public void onFinish(String response) {
Utility.handleWeatherResponse(AutoUpdateService.this, response);
}
@Override
public void onError(Exception e) {
e.printStackTrace();
}
});
}
}
在onStartCommend()方法中先是开启了一个子线程,然后在子线程中调用updateWeather()方法来更新天气
我们仍然会将服务器返回的天气数据交给Utility的handleWeatherResponse()方法去处理,这样就可以把最新的天气信息存储到SharedPreferences文件中
之后就是创建定时任务的技巧了,为了保证软件不会消耗过多的流量,这里将间隔时间设置为8小时,8小时后就应该执行到AutoUpdateReceiver的onReceive()方法中了
在receiver包下新建AutoUpdateReceiver继承自BroadcastReceiver
public class AutoUpdateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, AutoUpdateService.class);
context.startService(i);
}
}
这里只是在onReceive()方法中再次去启动AutoUpdateService,就可以实现后台定时更新的功能了
不过,我们还需要去激活AutoUpdateService这个服务
修改WeatherActivity中的代码
public class WeatherActivity extends Activity implements OnClickListener {
...
/**
* 从SharedPreference文件中读取存储的天气信息,并显示到界面上
*/
private void showWeather() {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
cityNameText.setText(pref.getString("city_name", ""));
tem1Text.setText(pref.getString("temp1", ""));
temp2Text.setText(pref.getString("temp2", ""));
weatherDespText.setText(pref.getString("weather_desp", ""));
publishText.setText("今天" + pref.getString("publish_time", "") + "发布");
currentDateText.setText(pref.getString("current_date", ""));
weatherInfoLayout.setVisibility(View.VISIBLE);
cityNameText.setVisibility(View.VISIBLE);
Intent intent = new Intent(this, AutoUpdateService.class);
startService(intent);
}
}
这里在showWeather()方法的最后加入启动AutoUpdateService这个服务的代码,这样只要一旦选中了某个城市并成功更新天气后,AutoUpdateService就会一直在后台运行,并保证每8小时更新一次天气
最后,不要忘了在AndroidManifest.xml中注册新增的服务和广播接收器
<service android:name="com.coolweather.app.service.AutoUpdateService" ></service>
<receiver android:name="com.coolweather.app.receiver.AutoUpdateReceiver"></receiver>