Android doze mode

2019-09-12 13:01发布

问题:

In My app I'll use an Alarm to notify user for event, the problem is on Android version 6.x-
The alarm is delivered after same minutes of the exact times.
This is only when the device enter on sleeping mode.

I tried to wakelock the device before the alarm, but to no avail.

Can anyone help me? this is my code

Set the alarms

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmCalendar.getTimeInMillis(), pendingIntent);
        if (minutesBefore > 0) {
            beforeCalendar.add(Calendar.MINUTE, -minutesBefore);
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, beforeCalendar.getTimeInMillis(), beforePendingIntent);
        }
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmCalendar.getTimeInMillis(), pendingIntent);
        if (minutesBefore > 0) {
            beforeCalendar.add(Calendar.MINUTE, -minutesBefore);
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, beforeCalendar.getTimeInMillis(), beforePendingIntent);
        }
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP, alarmCalendar.getTimeInMillis(), pendingIntent);

        if (minutesBefore > 0) {
            beforeCalendar.add(Calendar.MINUTE, -minutesBefore);
            alarmManager.set(AlarmManager.RTC_WAKEUP, beforeCalendar.getTimeInMillis(), beforePendingIntent);
        }
    }

Weaklock

when i receive the alarm by broadcastreceiver im try to wake up device from doze mode by this code

PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        //Object flags;

            wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Alarm_WakeLock");

        wl.acquire();

But the alarm still delivered after same minutes!!

回答1:

Doze mode is implemented to save the battery when the phone isn't used for some time. It does that by holding off operations like the AlarmManager.

If you really need the alarm to be fired in an exact time, use [setExactAndAllowWhileIdle()](https://developer.android.com/reference/android/app/AlarmManager.html#setExactAndAllowWhileIdle(int, long, android.app.PendingIntent)).

The docs says:

If you need to set alarms that fire while in Doze, use setAndAllowWhileIdle() or setExactAndAllowWhileIdle().



回答2:

From the docs, it looks like setExactAndAllowWhileIdle will fire even during doze, so that should have worked for you but you can try setAlarmClock.

Alarms set with setAlarmClock() continue to fire normally — the system exits Doze shortly before those alarms fire.

So you can use that. But it is intended to be used for what the user perceives as an alarm clock—a scheduled time at which the phone will alert the user (not just a calendar event). An icon is even displayed in the status bar as a physical alarm clock face, and many lockscreens will also inform the user of when the next alarm is scheduled.

ref https://www.bignerdranch.com/blog/diving-into-doze-mode-for-developers/