Search code examples
androidservicealarm

Android: How to repeat a service with AlarmManager every 15 minutes, but only run from 8:00AM to 18:00PM?


I need to check data update periodly, but the data is only updating during the daytime, so I want this repeating action run only in that time section for saving battery and bandwidth.

What should I do?


Solution

  • If the service is talking to the cloud with HTTP get/post/whatever requests, then note that a C2DM solution would net better battery life, and that a SyncAdapter solution could provide a few benefits. (I recommend watching the Google I/O videos on both topics.)

    The following code does something close to what you originally asked about.

    public class MyUpdateService extends IntentService
    {
      public MyUpdateService()
      {
        super(MyUpdateService.class.getSimpleName());
      }
    
      @Override
      protected void onHandleIntent(Intent intent)
      {
        // Do useful things.
    
        // After doing useful things...
        scheduleNextUpdate();
      }
    
      private void scheduleNextUpdate()
      {
        Intent intent = new Intent(this, this.getClass());
        PendingIntent pendingIntent =
            PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    
        // The update frequency should often be user configurable.  This is not.
    
        long currentTimeMillis = System.currentTimeMillis();
        long nextUpdateTimeMillis = currentTimeMillis + 15 * DateUtils.MINUTE_IN_MILLIS;
        Time nextUpdateTime = new Time();
        nextUpdateTime.set(nextUpdateTimeMillis);
    
        if (nextUpdateTime.hour < 8 || nextUpdateTime.hour >= 18)
        {
          nextUpdateTime.hour = 8;
          nextUpdateTime.minute = 0;
          nextUpdateTime.second = 0;
          nextUpdateTimeMillis = nextUpdateTime.toMillis(false) + DateUtils.DAY_IN_MILLIS;
        }
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC, nextUpdateTimeMillis, pendingIntent);
      }
    }