title: How to update a Widget in OREO (AlarmManager stops after some hours/days)
body: <p>I have a information widget which I'm updating each 60 seconds. Before OREO I did it using a service, but now, you can't do it because you can't use the service when the app is in the background, so I followed some posts here and used a alarm and AlarmManager to update the widget.</p>
  
  <p>The problem  is that it works for some hours, but in one or two days, the onReceive method of the alarm is not being called anymore. something happens because the alarm stops without user removing the widget, so the wiget stops getting updated.</p>
  
  <p>It seems that AlarmManager is not the best way to do this or I'm doing something wrong.</p>
  
  <p>This is my widget alarm receiver:</p>
  
  <pre><code>public class WidgetAlarmReceiver extends BroadcastReceiver {
      private final static String TAG = "WidgetAlarmReceiver";
  
      @Override
      public void onReceive(final Context context, Intent intent) {
          Log.d(TAG,"onReceive");
  
          ComponentName componentName = new ComponentName(context, AppWidget.class);
          RemoteViews remoteViews = WidgetHelper.getInstance().generateRemoteViews(context);
  
          AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);
      }
  }
  </code></pre>
  
  <p>This is the source code of the widget where I start the alarm:</p>
  
  <pre><code>public class AppWidget extends AppWidgetProvider {
      private AlarmManager alarmMgr;
      private PendingIntent alarmIntent;
  
  static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
      RemoteViews remoteViews = WidgetHelper.getInstance().generateRemoteViews(context);
      appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
  }
  
  @Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
      for (int appWidgetId : appWidgetIds) {
          updateAppWidget(context, appWidgetManager, appWidgetId);
      }
  }
  
  private void startWidgetAlarm(Context context){
      alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      Intent intent = new Intent(context, WidgetAlarmReceiver.class);
      intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
      alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
      alarmMgr.setInexactRepeating(AlarmManager.RTC, System.currentTimeMillis(), 60000, alarmIntent);
  }
  
  private void stopWidgetAlarm(Context context){
      alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      Intent intent = new Intent(context, WidgetAlarmReceiver.class);
      PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
      alarmMgr.cancel(sender);
  }
  
  @Override
  public void onEnabled(Context context) {
      super.onEnabled(context);
      startWidgetAlarm(context);
  }
  
  @Override
  public void onDisabled(Context context) {
      super.onDisabled(context);
      stopWidgetAlarm(context);
  }
  }
  </code></pre>
  
  <p>Portion of my manifest:</p>
  
  <pre><code>&lt;receiver android:name=".AppWidget"&gt;
      &lt;intent-filter&gt;
          &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&gt;
      &lt;/intent-filter&gt;
  
      &lt;meta-data
          android:name="android.appwidget.provider"
          android:resource="@xml/new_app_widget_info" /&gt;
  &lt;/receiver&gt;
  
  &lt;receiver android:name=".WidgetAlarmReceiver"  android:exported="false"/&gt;
  </code></pre>