For what I understood you just need one alarm, and I suppose all widgets will be all the same. So, the idea for your alarm is run on service, not on widget.
You shouldn't run long time actions on BroadcastReceiver.
We will use the onUpdate and not onEnable (because the design of this demo). Then aways we get a new widget we can perform the service.
AppWidgetProvider:
public class MyAppWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
{
ComponentName thisWidget = new ComponentName(context, MyAppWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
Intent intent = new Intent(context.getApplicationContext(), JStockAppWidgetService.class);
intent.setAction(JStockAppWidgetService.ALARM_UPDATE_ACTION);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.startService(intent);
}
@Override
public void onDisabled(Context context)
{
super.onDisabled(context);
Intent intent = new Intent(context.getApplicationContext(), JStockAppWidgetService.class);
intent.setAction(JStockAppWidgetService.ALARM_STOP_ACTION);
// I kept this just in case you wanna keep running your alarm without widget. You can just stopService here too.
context.startService(intent);
}
}
And here the Service:
public class JStockAppWidgetService extends Service {
public static final String ALARM_UPDATE_ACTION = "ALARM_UPDATE_ACTION";
public static final String ALARM_STOP_ACTION = "ALARM_STOP_ACTION";
//delay to refresh your widget
private int delay = 10000; //10 secs
private Thread myThread;
@Override
public void onStart(Intent intent, int startId) {
final int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
//running your timeout while is not interrupted
while(!Thread.currentThread().isInterrupted()) {
//we need to back to GUI thread
handler.post(new Runnable() {
@Override
public void run() {
runInMyGuiThread(allWidgetIds);
}
});
//everybody needs to sleep sometime =p
Thread.sleep(delay);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
};
String action = intent.getAction();
if(action == ALARM_UPDATE_ACTION) {
if(myThread != null)
myThread.interrupt();
myThread = new Thread(runnable);
myThread.start();
} else if(action == ALARM_STOP_ACTION && myThread != null) {
myThread.interrupt();
}
}
//here you are in GUI thread with all your widgets id
public void runInMyGuiThread(int[] allWidgetIds) {
for(int widgetId : allWidgetIds){
//do what you want to update each widget
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
This is just a little demo, you can stop the service or keep it running without widget, I will let with you.