It is a good idea to set the updatePeriodMillis in something like 900000 milliseconds. This will call your onUpdate method every 15 minutes. In the onUpdate method you can "refresh" your pending intents for your remote views. The other thing you can do is to perform a widget update every time you are changing your remote views. For example is the user press the button do what you have to do and then perform a widget update.
There are a number of reasons that a pending intent will be destroyed by the system thus leaving your remote views dead and all of them are hard to find and understand so the best practice is to update your widget once a while.
My research shows that 15 minutes is a good time frame for this. For example this is my onUpdate method which runs every 15 minutes for a widget with many buttons:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.d(TAG, "onUpdate");
super.onUpdate(context, appWidgetManager, appWidgetIds);
FullWidgetPreferencesHelper wp;
// If no specific widgets requested, collect list of all
if (appWidgetIds == null) {
appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, FullWidgetProvider.class));
}
for (int widgetId : appWidgetIds) {
Commands.FullWidgetUpdate(context, widgetId, 0); //<-- Update το widgetId
}
}
and the FullWidgetUpdate method is something like this:
...
views.setInt(R.id.cmdwifi, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_topleft_black));
views.setInt(R.id.cmdbluetooth, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
views.setInt(R.id.cmddata, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
views.setInt(R.id.cmdsync, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
views.setInt(R.id.cmdflight, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
views.setInt(R.id.cmdgps, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
views.setInt(R.id.cmdorientation, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_middle_black));
views.setInt(R.id.cmdvolume, "setBackgroundResource", ThemeResources.getThemeResource(themeId, R.drawable.btn_bck_topright_black));
...
final int PendingIntentFLAG = PendingIntent.FLAG_UPDATE_CURRENT;
Intent iWiFi = new Intent(cx, CommandsReceiver.class).setAction(CommandsReceiver.cmdwifi).setData(Uri.parse("custom:" + widgetID));
PendingIntent piWiFi = PendingIntent.getBroadcast(cx, 0, iWiFi, PendingIntentFLAG);
views.setOnClickPendingIntent(R.id.cmdwifi, piWiFi);
Intent iBT = new Intent(cx, CommandsReceiver.class).setAction(CommandsReceiver.cmdbt).setData(Uri.parse("custom:" + widgetID));
PendingIntent piBT = PendingIntent.getBroadcast(cx, 0, iBT, PendingIntentFLAG);
views.setOnClickPendingIntent(R.id.cmdbluetooth, piBT);
... and so on for other buttons ....
Hope this helps...