AlarmManager not working when device is sleeping in Android

I need some of the code to run every time, even if the application is killed or the device sleeps.

I am using AlarmManager

to achieve this and it works, but when the device sleeps for about five minutes, it Service

no longer gets called ... Does anyone know what I am doing wrong?

here is my code:

public class Profiler extends IntentService {

    public static final int ALARM_MANAGER_ID = 21436587;

    public Profiler() {
        super("Profiler");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        JodaTimeAndroid.init(getApplicationContext());
        System.out.println("Testing profiles");
        List<Profile> profiles = MainActivity.getStoredProfiles(getApplicationContext());

        if (profiles != null) {
            for (Profile profile : profiles) {
                if(profile.check()) {
                    profile.set(getApplicationContext());
                }
            }
        }

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent intent2 = new Intent(getApplicationContext(), Profiler.class);
        PendingIntent pIntent = PendingIntent.getService(getApplicationContext(), ALARM_MANAGER_ID, intent2, PendingIntent.FLAG_CANCEL_CURRENT);
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, DateTime.now().plusSeconds(10).getMillis(), pIntent);
    }
}

      

And one more question. Is this method a reliable service call?

Here is the log

07-24 11:31:24.654 17689-19078/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:31:34.671 17689-20364/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:31:34.673 17689-20364/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:31:34.674 17689-20364/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:31:44.692 17689-21571/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:31:44.693 17689-21571/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:31:44.694 17689-21571/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:31:54.704 17689-22753/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:31:54.705 17689-22753/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:31:54.706 17689-22753/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:32:04.717 17689-24015/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:32:04.718 17689-24015/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:32:04.718 17689-24015/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}
07-24 11:35:29.032 17689-17475/cz.fjerabek.soundprofiler I/System.out: Testing profiles
07-24 11:35:29.040 17689-17475/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":11,"minute":15}
07-24 11:35:29.050 17689-17475/cz.fjerabek.soundprofiler I/System.out: {"type":"Time","hour":0,"minute":0}

                                                                       [ 07-24 11:35:29.056 17476:17476 I/         ]
                                                                       power log dlsym ok

      

the application was launched at 11:31 am and now its 11:40, as you can see, the last execution of the code was at 11:35 and before that at 11:32 its 3 minutes, then it seems like it is called every 5 minutes.

I start the service with:

Intent bgServiceIntent = new Intent(getApplicationContext(), Profiler.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        if(checkNotificationPolicy(getApplicationContext())) {
            startService(bgServiceIntent);
        }
    } else {
        startService(bgServiceIntent);
    }

      

The device I'm using: HUAWEI P9 lite (VNS-L21)

+3


source to share


1 answer


Doze is most likely the cause of the problem .

From their docs regarding AlarmManager

:

To aid in scheduling alarms, Android 6.0 (API Level 23) introduces two new methods AlarmManager

: setAndAllowWhileIdle()

and setExactAndAllowWhileIdle()

. With these methods you can set alarms to be triggered even if the device is in Doze mode.

You should call the appropriate method AlarmManager

based on the API level to make sure the alarm goes off even when the device is sleeping:

if (Build.VERSION.SDK_INT >= 23) {
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
            alarmMillis, alarmIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
    alarmManager.setExact(AlarmManager.RTC_WAKEUP,
            alarmMillis, alarmIntent);
} else {
    alarmManager.set(AlarmManager.RTC_WAKEUP,
            alarmMillis, alarmIntent);
}

      

Consider the following:



Neither setAndAllowWhileIdle()

nor setExactAndAllowWhileIdle()

can a fire alarm be more than once every 9 minutes, per app.

As you said, you are testing a Huawei device.

Huawei (among other manufacturers) has implemented some battery saving features that can prevent alarms from triggering. You must add your application to "secure" applications.

Pay attention to the following questions: 1 and 2

It is not recommended to do this programmatically, the right solution might be to warn your users at startup (for example with help AlertDialog

) to manually make your application "protected" in Battery Manager.

+3


source







All Articles