Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android AlarmManager setRepeating doesn't repeat with long interval

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);
}
like image 596
Rob Avatar asked Sep 02 '11 18:09

Rob


2 Answers

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:

  • Add a logging statement to onReceive() of UpdateAlarmReceiver to confirm whether you are getting control at all, or whether the problem is (gasp!) with WakefulIntentService.
  • Try steadily increasing your period. Since you say 10 minutes works, try an hour, then four hours, etc., and try to get a sense when it breaks down.
  • "I'm actually using AutoKiller Memory Optimizer it doesn't have a whitelist this could be the issue? My app is running still though according the process list." -- I would disable all task killers, just to be sure they are not interfering.
like image 64
CommonsWare Avatar answered Nov 09 '22 16:11

CommonsWare


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.

like image 35
FoamyGuy Avatar answered Nov 09 '22 15:11

FoamyGuy