I implemented AlarmManager to wake up the phone once a day to complete the update task, update widgets and send notifications, if applicable.
I use setRepeating and ELAPSED_REALTIME_WAKEUP alarm is triggered for the first time ( SystemClock.elapsedRealtime()+60000 ) but it does not 86400000 milliseconds (after 24 hours).
Really struggling with this, I am happy to accept that I am doing something wrong or if there are better ways to achieve what I am trying to do. However, I think my code looks like a standard thing that people seem to do.
It is almost like a repeated alarm does not do what, according to him, should be in all cases. If I reduce the interval to say 10 minutes, it really works, my alarm triggers and service start over and over.
The nature of my application means that updating more than once a day is redundant. I need to find a realistic reliable solution.
Thanks for your time and hope you can point me in the right direction.
Here is my alarm implementation code ...
manifest:
<receiver android:name=".SystemChangeReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE" /> </intent-filter> </receiver> <receiver android:name=".UpdateAlarmReceiver" /> <service android:name=".UpdateService" /> <receiver android:name=".WidgetProviderSmall" android:label="@string/widget_small_label"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_small" /> </receiver> <receiver android:name=".WidgetProviderLarge" android:label="@string/widget_large_label"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_large" /> </receiver>
SystemChangeReceiver listens to the broadcast of the download, checks if the alarm should be set, if it does, it sets it.
SystemChangeReceiver :
@Override public void onReceive(Context context, Intent intent) { SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.prefs_name), 0); Boolean notifications = prefs.getBoolean("enable_updates", false); if(notifications == true) { Utils.setNotificationAlarm(context); } }
The setNotificationAlarm method, sets a repeating alarm ...
public static void setNotificationAlarm(Context context) { AlarmManager alarmManager=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, UpdateAlarmReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); alarmManager.setRepeating( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+60000, 86400000, pi); }
When the alarm starts my receiver, UpdateAlarmReceiver decides what to do, and using the WakefulIntentService starts my background update process, the handler for the service then updates the widgets and sends notifications as needed
UpdateAlarmReceiver :
public void onReceive(Context context, Intent intent) { WakefulIntentService.sendWakefulWork(context, UpdateService.class); }