Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AlarmManager stops working in Android 4.4.2 (using SetExact())

I'm setting in my code an alarm to go off in specific time.
The alarm mechanism works great on SDK < 19, but on 19 the alarms aren't fired.
Here is the code where I set the alarm :

public void SetAlarm(Context context, Long executionTime)
{

    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmReciever.class);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    // Only one alarm can live, so cancel previous.
    am.cancel(pi);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        am.set(AlarmManager.RTC_WAKEUP, executionTime, pi);
    } else {
        setAlarmFromKitkat(am, executionTime, pi);
    }
}

Since I'm setting the alarm using a Service I use GetApplicationContext() as the context.

The onReceive() code :

@Override
public void onReceive(Context context, Intent intent) {
    for (SchedulerListener listener : listeners) {
        listener.fetchAndRebuildNotification();
    }
}

Here is the declaration of the BroadcastReceiver :

<receiver 
        android:name="com.SagiL.myAppName.BroadCastReceivers.AlarmReciever" />

The callback runs a method in a service (which is still alive when the alarm supposed to fire, notice it doesn't starts one).

This whole thing is a library which is used in my app, and there I declare the receiver the same way.

Sometimes the alarm do fires once, but mostly it doesn't fire at all.

Has anyone experienced such a thing ?
I can't believe it's common to SDK 19 since a lot of apps are using AlarmManager and they will break too if it is common.

like image 314
SagiLow Avatar asked Dec 16 '13 20:12

SagiLow


2 Answers

I had a similar problem with my application. I found out that using 0 ad the id in getBroadcast(...); didn't work very well and caused numerous problems.

Try changing the id from 0 to the alarm's real id.

From:

PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

To:

PendingIntent pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
like image 78
Assaf Gamliel Avatar answered Nov 10 '22 02:11

Assaf Gamliel


It´s a late answer, but may help. In Android KitKat 4.4.xx a battery manager is integrated (my device: Huawei Ascend Mate 7). There is an option to kill background process and services of an app in the battery manager. Don´t know if the options are named similar to the german options, so just try:

  1. go to settings
  2. select save energy
  3. select detailed power consumption
  4. select Screen off: perform further
  5. enable Your app

It sounds simple, but that exactly was my problem. On Samsung Galaxy S3 with ICS everything worked like a charm. But bought a new device, the huawei, with Android 4.4.2, and suddenly my apps alarms didn´t work. After checking the system, I detected that option, enabled my app and now everything is fine. Not everything is a programming answer :) .

UPDATE

Since this answer was made, a lot happened in Android. For everybody with a similar problem: Since update to Marshmallow, there are two problems: first one is like described above, the second one is the doze mode:

Optimitzing Doze

Some devices, like my Huawei Ascend Mate 7, using both energy saving methods. So it isn´t enough to do what is described above. Also, you have to whitelist the app and use the new alarmManager methods setAllowWhileIdle(), setExactAndAllowWhileIdle() and setAlarmClock() .

Possible Problems

By whitelisting your app, you have to tell this the user. You can do it with a simple information at starting your app, for example a AlertDialog and/or you can use ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent to start the whitelisting screen. But be aware of this Action, because like reported from some developers, Google can suspend an app from playstore that is calling this action.

setAlarmClockshould also work, but if you do this, an alarm clock icon is on the top.

Testing

I have made some tests with that new documented doze mode and found out, that it usually works. But without whitelisting, the app falling to standby and ´alarmManager´ does not fire anymore, also not with that new methods. I tested it over night and the app is send to standby within about one hour. At a normal situation at day, where the user is active and often moves his device, it works without whitelisting.

like image 37
Opiatefuchs Avatar answered Nov 10 '22 03:11

Opiatefuchs