package com.hourlyweather.appwidget;
import org.joda.time.MutableDateTime;
import org.joda.time.chrono.ISOChronology;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.SystemClock;
import com.hourlyweather.ForecastCacher;
import com.hourlyweather.forecast.HourlyForecast;
/**
* A AppWidget for hourly Weather that displays a scrollable list of the current
* hourly forecast. Pressing the forecast will launch the main application at
* the current forecast position.
*
* @author dhgonsalves
*/
public class HourlyWeatherWidget extends AppWidgetProvider {
public static final String ACTION_FORECAST_UPDATE = "com.hourlyweather.widget.FORECAST_UPDATE";
public static final String EXTRA_FORECAST = "com.hourlyweather.forecast";
public static final String RETRIED_POLL = "com.hourlyweather.forecast.retry";
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
scheduleForecastUpdates(context);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// check if the forecast has been loaded yet
if (ForecastCacher.getCachedForecast(context) == null)
// run the forecast update service right now
context.startService(new Intent(context,
ForecastUpdateService.class));
else {
WidgetScrollList.populateList(context,
ForecastCacher.getCachedForecast(context));
}
}
public static void scheduleForecastUpdates(Context context) {
// before scheduling forecast updates cancel any existing ones first as
// a precaution
disableForecastUpdates(context);
// set up the update service
PendingIntent updateForecastIntent = PendingIntent.getService(context,
0, new Intent(context, ForecastUpdateService.class), 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
// get the next hour to schedule the update service
MutableDateTime startTime = new MutableDateTime(
System.currentTimeMillis());
startTime.setRounding(ISOChronology.getInstance().hourOfDay(),
MutableDateTime.ROUND_CEILING);
// schedule the forecastUpdateService to run every hour
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
startTime.getMillis(), AlarmManager.INTERVAL_HOUR,
updateForecastIntent);
System.out.println("updates scheduled!!");
}
public static void retryForecastUpdates(Context context) {
// set up the update service
Intent intent = new Intent(context, ForecastUpdateService.class);
intent.setData((Uri.parse("foobar://" + SystemClock.elapsedRealtime())));
intent.putExtra(RETRIED_POLL, true);
PendingIntent updateForecastIntent = PendingIntent.getService(context,
0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
// get the next hour to schedule the update service
MutableDateTime startTime = new MutableDateTime();
startTime.addMinutes(5);
// schedule the forecastUpdateService to run every hour
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
startTime.getMillis(), AlarmManager.INTERVAL_HOUR,
updateForecastIntent);
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
// handle forecast updates notifications from the app
if (ACTION_FORECAST_UPDATE.equals(intent.getAction())) {
HourlyForecast forecast = (HourlyForecast) intent.getExtras().get(
EXTRA_FORECAST);
WidgetScrollList.populateList(context, forecast);
}
}
/**
* Send a intent with a new forecast to force the widgets to update
*
* @param forecast
* @param context
*/
public static void updateWidgets(HourlyForecast forecast, Context context) {
Intent updateWidget = new Intent(
HourlyWeatherWidget.ACTION_FORECAST_UPDATE);
updateWidget.putExtra(HourlyWeatherWidget.EXTRA_FORECAST, forecast);
context.sendBroadcast(updateWidget);
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
disableForecastUpdates(context);
}
/**
* cancels any pending scheduled forecast updates
*
* @param context
*/
private static void disableForecastUpdates(Context context) {
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
PendingIntent updateForecastIntent = PendingIntent.getService(context,
0, new Intent(context, ForecastUpdateService.class), 0);
alarmManager.cancel(updateForecastIntent);
System.out.println("updates cancelled");
}
}