I've implemented AlarmManager to wake the phone once a day to perform an update task, update widgets and send notifications if applicable.
I'm using setRepeating
and ELAPSED_REALTIME_WAKEUP
The alarm is triggered the first time (SystemClock.elapsedRealtime()+60000
)
but it doesn't get triggered 86400000
milliseconds (24 hours) later.
Really struggling with this, I'm happy to accept im doing something wrong or if there are better ways to achieve what I'm trying to do. However I think my code looks like the standard thing people seem to do.
It's almost like the repeating alarm doesn't do what it says it should in all cases. If I reduce the interval to say 10 minutes it does work, my alarm triggers and the service is run over and over.
The nature of my app means updating more than once a day is overkill. I need to find a realistic reliable solution to this.
Thanks for your time & hope you can point me in the right direction.
Here's 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 for the boot broadcast, checks if an alarm needs to 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 up the 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 triggers my receiver UpdateAlarmReceiver
decides what to do and using WakefulIntentService
runs my background update process, the handler for the service then updates widgets and sends notifications as required
UpdateAlarmReceiver
:
public void onReceive(Context context, Intent intent) {
WakefulIntentService.sendWakefulWork(context, UpdateService.class);
}
There's nothing obviously wrong.
For a long period like that, though, I'd recommend RTC_WAKEUP
, so you can arrange for it to occur in the middle of the night or perhaps at a user-selectable time, rather than every 24 hours from a semi-random start point. It's possible RTC_WAKEUP
will give you better results.
Also:
onReceive()
of UpdateAlarmReceiver
to confirm whether you are getting control at all, or whether the problem is (gasp!) with WakefulIntentService
.Have you tried setting it not to repeat. Then when it fires off you set the next single shot alarm for 24 hours later? This would function like a repeating alarm but might avoid some of the problems you are seeing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With